2014年4月10日 星期四

讓 Vim、Screen 支援 256 色

Vim 設定使用 256 色很簡單, 只要在 .vimrc 加一行設定就完成了.
  1. vim ~/.vimrc
  2. set t_Co=256 " 加這行即可
但是設完後, 一直沒有作用, 離開 Screen 才發現 256 色有出現, 是 Screen 沒有支援 256 色的問題, 所以再來設定讓 Screen 支援 256 色.

設定 Screen 支援 256 色

Screen 設定 256 色的模式, 主要是 xterm 的問題, 設法也是一行就解決了.
  1. vim ~/.screenrc
  2. termcapinfo xterm 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm' # 開啟 256 色模式
這樣子就完成 Vim、Screen 的設定囉~ 於是就可以在 .vimrc 試試各種配色設定, ex:
  • colorscheme darkblue
  • colorscheme desert
  • colorscheme default ... 等.

Mysql備用筆記

變更資料庫預設語(character_set_server),這個只有mysql 4 才須要改
character_set_server = utf8
存檔後,重新啟重mysql
使用mysqladmin variables -u root -p 確認character_set_server 及 character_set_database 是否變為 utf8
註:不同的下指令方式得到不同的結果
towns 使用 mysqladmin variables -u root -p 出現了以下五個值皆改為UTF8
character_set_client
character_set_connection
character_set_database
character_set_results
character_set_server
towns 登入資料庫後(mysql -u root -p),再使用 show variables;,得到以下結果
character_set_client  ==> latin1
character_set_connection  ==> latin1
character_set_database ==> utf8
character_set_results ==> latin1
character_set_server ==> utf8

 資料庫編碼轉換問題
這個問題只會出現在 mysql 4版中
使用指令 SET NAMES utf8;將character_set_client、character_set_connection、character_set_results改為 UTF8,這個是臨時性的修改

取消pcschool在資料庫裡delete權限:
revoke delete on *.* from pcschool@localhost;

上例是取消delete權限,如果是要取消所有權限:
revoke all privileges on *.* from pcschool@localhost;

revoke on指令只能移除帳號權限,但無法將帳號刪除。若要將帳號刪除,請以MySQL管理者root身份登入MySQL後,先執行「use mysql」指令使用mysql資料庫,再輸入「delete from user where user='pcschool';」刪除使用者資料,並執行「flush privileges;」指令,讓系統重新整理

MySQL 語法匯整

1. 基礎語法

操作功能SQL 語法
說明
建立資料庫create database 資料庫名稱;
列出所有資料庫show databases;
刪除資料庫drop database 資料庫名稱;
使用資料庫use 資料庫名稱;
建立資料表create table 資料表名稱(
sn integer auto_increment primary key,
name char(20),
mail char(50),
home char(50),
messages char(50)
);
常用資料庫資料型態
1. INT (整數)
2. CHAR (1~255字元字串)
3. VARCHAR (不超過255字元不定長度字串)
4. TEXT (不定長度字串最多65535字元)
 
列出資料表欄位資訊describe 資料表名稱;
修改資料表欄位alter table 資料表名稱
change column 原來欄位名稱
新欄位名稱資料型態;
新增資料表欄位alter table 資料表名稱 add column 欄位名稱 資料型態;
刪除資料表欄位alter table 資料表名稱 drop column 欄位名稱;
刪除資料表drop table 資料表名稱;
清空資料表truncate table 資料表名稱;只清除資料並保留結構、欄位、索引 …
插入欄位資料insert into 資料表名稱(欄位1,欄位2,欄位3,欄位4, ...... 欄位N)
values('值1','值2','值3','值4', ...... '值N');
更新修改欄位資料update 資料表名稱 set 欄位1='值1',欄位2='值2',欄位3='值3',... 欄位N='值N'
where 條件式 (例如 sn='5' 或 name='塔司尼' );
查詢單一欄位資料select 欄位名 from 資料表名稱;
查詢多個欄位資料select 欄位名, 欄位名, 欄位名 from 資料表名稱;
查詢欄位資料的唯一值select distinct 欄位名 from 資料表名稱;重複值只列一次
查詢所有欄位資料select * from 資料表名稱;
條件式查詢select * from 資料表名稱 where 條件式 (例如 sn='5');(=, <, >, !=)
條件式查詢 andselect * from 資料表名稱 where 條件式1 and 條件式2;
條件式查詢 orselect * from 資料表名稱 where 條件式1 or 條件式2;
查詢某一範圍 betweenselect * from 資料表名稱 where 欄位名 between 值1 and 值2;值為數字
查詢空值欄位的資料select * from 資料表名稱 where 欄位名 is nullnot null;
查詢特定筆數資料select * from 資料表名稱 limit 8, 10;第9筆開始選取10筆
查詢結果遞增排序select * from 資料表名稱 order by欄位名;
查詢結果遞減排序select * from 資料表名稱 order by欄位名 desc ;
查詢比對字串列出單一欄位select 欄位名 from 資料表名稱 where 欄位名 like '%字串%';
查詢比對字串列出所有欄位select * from 資料表名稱 where 欄位名 like '%字串%';
刪除條件值資料delete from 資料表名稱 where 條件式 (例如 sn='5' 或 id='91001' );
刪除條件值資料delete from 資料表名稱 where 條件式1 
and
 條件式2;
刪除條件值資料delete from 資料表名稱 where 條件式1 or 條件式2;
比對刪除條件值資料delete from 資料表名稱 where 欄位名 like '%字串%';

2. 進階語法

操作功能SQL 語法
說明
查看正在執行的行程。show processlist;
查看 Master 的狀態。show master status;
查看 Slave 的狀態。show slave status\G;

MySQL的重要語法

一、帳號與權限
設定 root 和其他 user 的密碼
  • mysqladmin -u root password '新密碼'
  • mysqladmin -u root -p
  • Enter password:    此時再輸入密碼(建議採用)
  • use mysql;
    mysql> UPDATE user SET password=password('新密碼') where user='root'; 
      只改 root 的密碼,如果沒有用 where ,則表示改全部 user 的密碼
  • mysql> FLUSH PRIVILEGES; 在 mysql 資料庫內,一定要用 flush 更新記憶體上的資料
刪除空帳號
  • mysql> DELETE FROM user WHERE User = '';
  • mysql> FLUSH PRIVILEGES;
     
建立新帳號
  • mysql> GRANT 權限 ON 資料庫或資料表 TO 使用者 IDENTIFIED BY '密碼';
      權限
       
      資料庫或資料表
       *.* 所有資料庫裡的所有資料表
       * 預設資料庫裡的所有資料表
       資料庫.* 某一資料庫裡的所有資料表   
       資料庫.資料表 某一資料庫裡的特定資料表
       資料表  預設資料庫裡的某一資料表
設定/修改權限  
  • 用 root 登入 MySQL
      mysqladmin -u root -p
     Enter password:   
  • mysql> GRANT all ON db35.* TO s35@'localhost' IDENTIFIED BY 's35';
       把 db35 這個資料庫(含其下的所有資料表),授權給 s35,從 localhost 上來,密碼為s35
     
  • mysql> GRANT all ON *.*  把所有資料庫及資料表授權給別人,太危險了!
     
  • mysql> GRANT all??? ON www.* TO '*'@'*' IDENTIFIED BY '';
        把 www 這個資料庫(含其下的所有資料表),授權給 任何機器任何人,無密碼(通常給不特定人士使用)
     
  • mysql> FLUSH PRIVILEGES;   (最後一定要強迫更新權限)

二、資料庫/資料表/欄位的操作
建立資料庫 CREATE DATABASE 資料庫名;
語法:CREATE DATABASE db_name
使用資料庫 USE 資料庫名;
語法:USE db_name
刪除資料庫 DROP DATABASE 資料庫名;
語法:DROP DATABASE [IF EXISTS] db_name
 
建立資料表
 CREATE TABLE 資料表名 (欄位1 資料型態, 欄位2 資料型態, ......);
語法:
CREATE TABLE [IF NOT EXISTS] tbl_name (create_definition,...) [table_options] [select_statement]
例:
craete database basic;
use basic;
create table basic(
  no char(4)
  name char(10)
  id char(10));
create_definition:
  col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT]
            [PRIMARY KEY] [reference_definition]
  or    PRIMARY KEY (index_col_name,...)
  or    KEY [index_name] KEY(index_col_name,...)
  or    INDEX [index_name] (index_col_name,...)
  or    UNIQUE [INDEX] [index_name] (index_col_name,...)
  or    [CONSTRAINT symbol] FOREIGN KEY index_name (index_col_name,...)
            [reference_definition]
  or    CHECK (expr)
資料結構(type):
資料型態說明
TINYINT有符號的範圍是-128127, 無符號的範圍是0255
SMALLINT有符號的範圍是-3276832767, 無符號的範圍是065535
MEDIUMINT有符號的範圍是-83886088388607, 無符號的範圍是016777215
INT有符號的範圍是-21474836482147483647, 無符號的範圍是04294967295
INTEGERINT的同義詞。
BIGINT有符號的範圍是-9223372036854775808到 9223372036854775807,無符號的範圍是0到18446744073709551615。
FLOAT單精密浮點數字。不能無符號。允許的值是-3.402823466E+38到- 1.175494351E-38,0 和1.175494351E-38到3.402823466E+38。
DOUBLE雙精密)浮點數字。不能無符號。允許的值是- 1.7976931348623157E+308到-2.2250738585072014E-308、 0和2.2250738585072014E-308到1.7976931348623157E+308。
DOUBLE PRECISIONDOUBLE的同義詞。
REALDOUBLE的同義詞。
DECIMALDECIMAL值的最大範圍與DOUBLE相 同。
NUMERICDECIMAL的同義詞。
DATE日期。支援的範圍是'1000-01-01'到'9999-12-31'。
DATETIME日期和時間組合。支援的範圍是'1000-01-01 00:00:00''9999-12-31 23:59:59'
TIMESTAMP時間戳記。範圍是'1970-01-01 00:00:00'到2037年的某時。
TIME一個時間。範圍是'-838:59:59''838:59:59'
YEAR2或4位數字格式的年(內定是4位)。允許的值是1901到2155。
CHAR固定長度,1 ~ 255個字元。
VARCHAR可變長度,1 ~ 255個字元。
TINYBLOB

TINYTEXT最大長度為255(2^8-1)個字符。
MEDIUMBLOB

MEDIUMTEXT最大長度為16777215(2^24-1)個字符。
LONGBLOB

LONGTEXT最大長度為4294967295(2^32-1)個字符。
ENUM一個ENUM最多能有65535不同的值。  
SET一個SET最多能有64個成員。

index_col_name:
        col_name [(length)]
reference_definition:
        REFERENCES tbl_name [(index_col_name,...)]
                   [MATCH FULL | MATCH PARTIAL]
                   [ON DELETE reference_option]
                   [ON UPDATE reference_option]
reference_option:
        RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
table_options:
        type = [ISAM | MYISAM | HEAP]
or      max_rows = #
or      min_rows = #
or      avg_row_length = #
or      comment = "string"
or      auto_increment = #
select_statement:
        [ | IGNORE | REPLACE] SELECT ...  (Some legal select statement)

刪除資料表 DROP TABLE 資料表名;
語法:DROP TABLE [IF EXISTS] tbl_name [, tbl_name,...]
改變資料表結構(新增/刪除欄位、建立/取消索引、改變欄位資料型態、欄位重新命 名)
語法:
ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...]
alter_specification:
        ADD [COLUMN] create_definition [FIRST | AFTER column_name ]
  or    ADD INDEX [index_name] (index_col_name,...)
  or    ADD PRIMARY KEY (index_col_name,...)
  or    ADD UNIQUE [index_name] (index_col_name,...)
  or    ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
  or    CHANGE [COLUMN] old_col_name create_definition
  or    MODIFY [COLUMN] create_definition
  or    DROP [COLUMN] col_name
  or    DROP PRIMARY KEY
  or    DROP INDEX key_name
  or    RENAME [AS] new_tbl_name
  or    table_option
範例:
 欄位重新命名
 mysql> ALTER TABLE t1 CHANGE a b INTEGER;
  將資料表 t1 欄位 a 改名為 b (其資料型態是 integer)
 改變欄位資料型態
 mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
 mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
  將資料表 t1 欄位 b 的資料型態改為 bigint not null 
 mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10)); 
 mysql> ALTER TABLE t1 RENAME t2;
  將資料表 t1 改名為 t2
 mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);
  將資料表 t2 欄位 a 資料型態由 integer 改為 tinyint not null ,欄位 b 改名為 c 資料型態改為 char(20)
 mysql> ALTER TABLE t2 ADD d TIMESTAMP;
  在資料表 t2 增加新欄位 d 資料型態是 timestamp
 mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);
  在資料表 t2 ,對 d 欄位做索引,並以欄位 a 作為主索引鍵
 mysql> ALTER TABLE t2 DROP COLUMN c;
  刪除欄位 c
  mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT, ADD INDEX (c);
  新增欄位 c,並做索引(做索引的欄位必須為 not null )
資料表最佳化 OPTIMIZE TABLE 資料表名
語法:OPTIMIZE TABLE tbl_name
 欄位長度有變動、刪除大量資料,都應進行資料表最佳化
三、紀錄的操作
插入一筆或多筆紀錄 INSERT INTO 資料表(欄位1,欄位2,......) VALUES(值1,值2,......), (值1,值2,......), ........
  (MySQL 3.22.5 以後可插入多筆記錄)
語法:
    INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name [(col_name,...)]
        VALUES (expression,...),(...),...
or  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name [(col_name,...)]
        SELECT ...
or  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name
        SET col_name=expression, col_name=expression, ...
範例:
 mysql> INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);
  不可寫成
 mysql> INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);
  因為:欄位 col1 的值先填入後,才可以計算欄位 col2
從檔案讀入資料
語法:
 LOAD DATA [LOCAL] INFILE 'file_name.txt' [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [FIELDS
        [TERMINATED BY '\t']    每一欄位以某字元分開(內定是 tab)
        [OPTIONALLY] ENCLOSED BY "]   每一欄位以某字元括住(內定是不使用括號)
        [ESCAPED BY '\\' ]]     
    [LINES TERMINATED BY '\n']  設定換行的字元(內 定是 \n)
    [IGNORE number LINES]    忽略最前面幾行(最前面幾筆記錄不抄進來)
    [(col_name,...)]
範例:
 mysql> USE db1;
 mysql> LOAD DATA INFILE "./data.txt" INTO TABLE db2.my_table;
  從目前 MySQL 目錄讀入 data.txt
 mysql> LOAD DATA INFILE "./88.txt" INTO TABLE TEACHER FIELDS TERMINATED BY ' ' ;
  從目前 MySQL 目錄(我的在 /var/lib/mysql )讀入 data.txt ,每一欄位以 空白 分開
 mysql> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata (col1,col2,...);
  只將 persondata.txt 裡某些欄位的資料抓過來 
刪除紀錄 DELETE [LOW-PRIORITY] FROM 資料表名 WHERE 條件 [LIMIT rows]
語法:
 DELETE [LOW_PRIORITY] FROM tbl_name
    [WHERE where_definition] [LIMIT rows]
  LOW-PRIORITY 是等到沒有用戶端使用時再刪
  LIMIT rows 限制刪除紀錄的筆數
範例:
 mysql> DELETE FROM 資料表名;
  刪除所有紀錄
 mysql> DELETE FROM 資料表名 WHERE 1>0;
  刪除所有紀錄,但速度較慢,方便在螢幕上看

更新一筆紀錄 (語法與 INSERT 相同)
 REPLACE INTO 資料表(欄位1,欄位2,......) VALUES(值1,值2,......)
語法:
REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tbl_name [(col_name,...)]
        VALUES (expression,...)
or  REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tbl_name [(col_name,...)]
        SELECT ...
or  REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tbl_name
        SET col_name=expression, col_name=expression,...
更新多筆紀錄
語法:
UPDATE [LOW_PRIORITY] tbl_name SET col_name1=expr1,col_name2=expr2,...     [WHERE where_definition]
  如果沒有設定 WHERE 條件,則整個資料表相關的欄位都更新
範例:
 mysql> UPDATE persondata SET age=age+1;
  將資料表 persondata 中,所有 age 欄位都加 1
 mysql> UPDATE persondata SET age=age*2, age=age+1;
  將資料表 persondata 中,所有 age 欄位都*2,再加 1
四、資料的輸出
SELECT
語法:
 SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [DISTINCT | ALL]
    select_expression,...
    [INTO OUTFILE 'file_name' export_options]
    [FROM table_references
        [WHERE where_definition]
        [GROUP BY col_name,...]
        [HAVING where_definition]
        [ORDER BY {unsigned_integer | col_name} [ASC | DESC] ,...]
        [LIMIT [offset,] rows]
        [PROCEDURE procedure_name] ]
範例:
排序輸出select * from 資料表名 order by 欄位名1,欄位名2,欄位名3...... 
反向排序輸出 
select * from 資料表名 order by 欄位名1,欄位名2,欄位名3...... desc

 
mysql> select concat(last_name,', ',first_name) AS full_name

      from mytable ORDER BY full_name;



 mysql> select t1.name, t2.salary from employee AS t1, info AS t2

           where t1.name = t2.name;

  顯示資料庫 employee(別名 t1) 裡,資料表 t1 的欄位 name 和 資料表 t2 的欄位 salary 當.....

 mysql> select t1.name, t2.salary from employee t1, info t2           where t1.name = t2.name;



 mysql> select college, region, seed from tournament

           ORDER BY region, seed;

 mysql> select college, region AS r, seed AS s from tournament

           ORDER BY r, s;

 mysql> select college, region, seed from tournament

           ORDER BY 2, 3;



 mysql> select col_name from tbl_name HAVING col_name > 0;



 mysql> select col_name from tbl_name WHERE col_name > 0;



 mysql> select user,max(salary) from users

           group by user HAVING max(salary)>10;



 mysql> select user,max(salary) AS sum from users

           group by user HAVING sum>10;



 mysql> select * from table LIMIT 5,10;  # Retrieve rows 6-15



 mysql> select * from table LIMIT 5;     # Retrieve first 5 rows

  •  
在命令列下進行批次處理:
shell> mysql -h host -u user -p < batch-file
Enter password: ********
TypeBytesFromTo
TINYINT1-128127
SMALLINT2-3276832767
MEDIUMINT3-83886088388607
INT4-21474836482147483647
BIGINT8-92233720368547758089223372036854775807

Column type``Zero'' value
DATETIME'0000-00-00 00:00:00'
DATE'0000-00-00'
TIMESTAMP00000000000000 (length depends on display size)
TIME'00:00:00'
YEAR0000

Column typeDisplay format
TIMESTAMP(14)YYYYMMDDHHMMSS
TIMESTAMP(12)YYMMDDHHMMSS
TIMESTAMP(10)YYMMDDHHMM
TIMESTAMP(8)YYYYMMDD
TIMESTAMP(6)YYMMDD
TIMESTAMP(4)YYMM
TIMESTAMP(2)YY

TypeMax.sizeBytes
TINYTEXT or TINYBLOB2^8-1255
TEXT or BLOB2^16-1 (64K-1)65535
MEDIUMTEXT or MEDIUMBLOB2^24-1 (16M-1)16777215
LONGBLOB2^32-1 (4G-1)4294967295

ValueCHAR(4)Storage requiredVARCHAR(4)Storage required
''' '4 bytes''1 byte
'ab''ab '4 bytes'ab'3 bytes
'abcd''abcd'4 bytes'abcd'5 bytes
'abcdefgh''abcd'4 bytes'abcd'5 bytes

ValueIndex
NULLNULL
""0
"one"1
"two"2
"three"3

Other vendor typeMySQL type
BINARY(NUM)CHAR(NUM) BINARY
CHAR VARYING(NUM)VARCHAR(NUM)
FLOAT4FLOAT
FLOAT8DOUBLE
INT1TINYINT
INT2SMALLINT
INT3MEDIUMINT
INT4INT
INT8BIGINT
LONG VARBINARYMEDIUMBLOB
LONG VARCHARMEDIUMTEXT
MIDDLEINTMEDIUMINT
VARBINARY(NUM)VARCHAR(NUM) BINARY

Column typeStorage required
TINYINT1 byte
SMALLINT2 bytes
MEDIUMINT3 bytes
INT4 bytes
INTEGER4 bytes
BIGINT8 bytes
FLOAT(X)4 if X <= 24 or 8 if 25 <= X <= 53
FLOAT4 bytes
DOUBLE8 bytes
DOUBLE PRECISION8 bytes
REAL8 bytes
DECIMAL(M,D)M+2 bytes if D > 0, M+1 bytes if D = 0 (D+2, if M < D)
NUMERIC(M,D)M+2 bytes if D > 0, M+1 bytes if D = 0 (D+2, if M < D)

Column typeStorage required
DATE3 bytes
DATETIME8 bytes
TIMESTAMP4 bytes
TIME3 bytes
YEAR1 byte

Column typeStorage required
CHAR(M)M bytes, 1 <= M <= 255
VARCHAR(M)L+1 bytes, where L <= M and 1 <= M <= 255
TINYBLOBTINYTEXTL+1 bytes, where L < 2^8
BLOBTEXTL+2 bytes, where L < 2^16
MEDIUMBLOBMEDIUMTEXTL+3 bytes, where L < 2^24
LONGBLOBLONGTEXTL+4 bytes, where L < 2^32
ENUM('value1','value2',...)1 or 2 bytes, depending on the number of enumeration values (65535 values maximum)
SET('value1','value2',...)1, 2, 3, 4 or 8 bytes, depending on the number of set members (64 members maximum)

MySQL Master-Master Replication 同步

可以先看看 MySQL Master Slave Replication,中文網站可以上 google 查詢或者是看看這一篇:MySQL 設定 Replication (Master – Slave),基本上設定還蠻容易的,如果會 Master 同步到 Slave 的話,那 MySQL Master-Master 只是在用相同的方法在做一遍,如果不懂 MMM 的可以先參考這一篇:MySQL Master-Master Replication Manager(1) – 簡介,這篇寫的很清楚,今天看了文章,我實做起來,遇到一些問題,其實還蠻奇怪的,所以底下就來紀錄一下步驟,順便也說明一下。 實做兩台 Ubuntu 機器: db1:192.168.1.1 db2:192.168.1.2 先設定 db1: 目前我都是在 Ubuntu 7.10 底下實做的,那基本上只要有支援 MySQL 的 Linux 或者 FreeBSD 機器都可以實做這個方法: 步驟一:先修改 my.cnf 這個檔案: FreeBSD 的話在:/var/db/mysql/my.cnf Ubuntu:/etc/mysql/my.cnf 有的版本是在 /etc/my.cnf 所以不太一定,請依照自己的作業系統 修改: 
#
# bind-address 請 mark 起來,因為我們必須讓 MySQL Listen 各個不同的 IP Address
#bind-address           = 127.0.0.1
#
# server id 請記得每台機器都設定不同喔
#
server-id               = 1
log_bin                 = /var/log/mysql/mysql-bin.log
步驟一的部份也請先在 db2 的機器先設定一次,然後重新啟動 mysql 步驟二:設定 mysql 權限
mysql -u root -p
#
# 先設定 replication 這個帳號密碼是 slave 這個可以自己改掉
#
mysql> GRANT replication slave on *.* to 'replication'@'%' identified by 'slave';
#
#  這個是官方的寫法,可以按照這底下去寫就可以了
# 
mysql> change master to master_host='192.168.1.2', master_port=3306, master_user='replication', master_password='slave';
#
# 底下是 Master 機器的 bin log file
# master_log_file='mysql-bin.000004',
# master_log_pos=98;
# 可以利用 SHOW MASTER STATUS; 來取得這兩個的值
mysql> change master to master_host='192.168.1.2', master_port=3306, master_user='replication', master_password='slave', master_log_file='mysql-bin.000004', master_log_pos=98;
先到 db2 執行 SHOW MASTER STATUS; 會得到底下結果 
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |      189 |              |                  |
+------------------+----------+--------------+------------------+
 那這樣就可以知道 master_log_file=’mysql-bin.000001′, master_log_pos=189; 步驟三:測試觀看 mysql slave 重新啟動 mysql 
/etc/init.d/mysql restart
#
# 啟動 slave 
#
mysql> START slave;
#
# 觀看 slave 狀態 
#
mysql> show slave status \G;
1 (by appleboy46) 請注意下面這兩行必須為 YES 
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
 這樣才算代表成功了,不然就是失敗的。 先設定 db2: 步驟一:先修改 my.cnf 這個檔案: FreeBSD 的話在:/var/db/mysql/my.cnf Ubuntu:/etc/mysql/my.cnf 有的版本是在 /etc/my.cnf 所以不太一定,請依照自己的作業系統 修改: 
#
# bind-address 請 mark 起來,因為我們必須讓 MySQL Listen 各個不同的 IP Address
#bind-address           = 127.0.0.1
#
# server id 請記得每台機器都設定不同喔
#
server-id               = 1
log_bin                 = /var/log/mysql/mysql-bin.log
步驟二:設定 mysql 權限
mysql -u root -p
#
# 先設定 replication 這個帳號密碼是 slave 這個可以自己改掉
#
mysql> GRANT replication slave on *.* to 'replication'@'%' identified by 'slave';
#
#  這個是官方的寫法,可以按照這底下去寫就可以了
# 
mysql> change master to master_host='192.168.1.1', master_port=3306, master_user='replication', master_password='slave';
#
# 底下是 Master 機器的 bin log file
# master_log_file='mysql-bin.000004',
# master_log_pos=98;
# 可以利用 SHOW MASTER STATUS; 來取得這兩個的值
mysql> change master to master_host='192.168.1.1', master_port=3306, master_user='replication', master_password='slave', master_log_file='mysql-bin.000004', master_log_pos=98;
步驟三:測試觀看 mysql slave 重新啟動 mysql 
/etc/init.d/mysql restart
#
# 啟動 slave 
#
mysql> START slave;
#
# 觀看 slave 狀態 
#
mysql> show slave status \G;
 如果遇到 
Slave_IO_Running: no
Slave_SQL_Running: no
 這樣的話請依照下面步驟:
#
# 停止跟清除 SLAVE 
#
mysql> STOP SLAVE;
mysql> RESET SLAVE;
#
# 停止 mysql
#
/etc/init.d/mysql stop
#
# 刪除 bin log 檔案
#
rm -rf /var/log/mysql/mysql-bin.*
#
# 啟動 mysql 
#
/etc/init.d/mysql start
#
# 在設定一次 master ip 資訊
#
mysql> change master to master_host='192.168.1.1', master_port=3306, master_user='replication', master_password='slave';
#
# 啟動 slave
#
mysql> START SLAVE;

MySQL 設定 Replication (Master - Slave)

MySQL 設定寫入 Master 後, 自動 Replication 到 Slave 去, 運作基本原理是:
  1. INSERT/UPDATE/DELETE 語法, 自動寫入 Master 的 binlog file.
  2. 由 GRANT REPLICATION 授權的帳號, 自動將 SQL 語法 repl 到 Slave 的 DB 執行.
  3. 因而完成 Replication 的動作.

設定 Replication 的操作 (Master)

  1. $ sudo vim /etc/mysql/my.cnf # 下面是 Debian Linux 的設定, 找到下面的設定, 新增/修改 成下面這樣子.
    #bind-address           = 127.0.0.1
    server-id               = 1
    log_bin                 = /var/log/mysql/mysql-bin.log
    # 若是 innodb, 且有用 transaction 的話, 需再加入下面兩行
    innodb_flush_log_at_trx_commit=1
    sync_binlog=1
  2. $ sudo /etc/init.d/mysql restart
  3. $ mysql -u root -p # 進入 mysql
  4. mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY 'repl_pass'; # 先假設 帳號 repl, 密碼 repl_pass, 此步驟是 設定 repl 的帳號/密碼, 格式: GRANT REPLICATION SLAVE ON *.* TO
    'repl_user'@'%.mydomain.com' IDENTIFIED BY 'repl_password'; (Replace
    <some_password>with a real password!)
  5. mysql> FLUSH TABLES WITH READ LOCK; # 先讓 DB 不要再寫資料進去
  6. mysql> SHOW MASTER STATUS; # 這邊資料都要記好, 等一下設定 Slave 要用
    +----------------------+------------+------------------+----------------------+
    | File                     | Position   | Binlog_Do_DB | Binlog_Ignore_DB  |
    +----------------------+------------+------------------+----------------------+
    | mysql-bin.000014  |      232   |                      |                          |
    +----------------------+------------+------------------+----------------------+
  7. mysql> quit # 離開, 準備倒資料
  8. 倒資料, 可以由下述的方法倒, 此次採用步驟 1
    1. $ mysqldump -u root -p DB > dbdump.sql
    2. $ mysqldump --all-databases --lock-all-tables >dbdump.sql
    3. $ mysqldump --all-databases --master-data >dbdump.sql # --master-data: 會自動將CHANGE MASTER 的語法帶在裡面
  9. $ mysql -u root -p # 進入 mysql
  10. mysql> UNLOCK TABLES; # dump 完資料後, 進去 mysql 解除唯讀
  11. 再來就是將 dbdump.sql scp 到 Slave 去即可.
  12. Master 就到此為止.

設定 Replication 的操作 (Slave)

  1. $ sudo vim /etc/mysql/my.cnf
    server-id               = 2  # server-id 不能與其它機器相同
    log_bin                 = /var/log/mysql/mysql-bin.log
  2. $ mysql -u root -p # 進入 mysql
  3. mysql> create database DBNAME;
  4. mysql> use DBNAME; source dbdump.sql; 或 $ mysql -u root -p DBNAME < dbdump.sql
  5. mysql> CHANGE MASTER TO
         MASTER_HOST='MASTER_HOSTNAME',
         MASTER_USER='repl',
         MASTER_PASSWORD='repl_pass',
         MASTER_LOG_FILE='mysql-bin.000014',
         MASTER_LOG_POS=232; # 這邊就要用到之前 Master 抄下來的值.
  6. mysql> START SLAVE; # 這樣子就會開始 Replication 了, 會將 LOG_POS 之後新的資料開始 sync 回來.
  7. mysql> show master status; # 檢查一下設定
  8. mysql> show slave status; # 檢查一下設定, 看是不是有異常狀況.

測試

  1. 在 master: mysql> create database test2;
  2. 在 slave: mysql> show database; # 應該會看到 test2
  3. 在 master 上的任何操作應該都會馬上 replication 到 slave 去.

ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES

mysql> grant replication slave,replication client on database1.* to uncoccpy@'192.168.%.%' identified by 'rePlication08#23';
ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES


這個是因為replication slave,replication不能授權給單個數據庫
我們需要在my.cnf中這樣的配置
可以在選擇在那端進行過濾
master端:
binlog-do-db= test #二進制需要同步的數據庫名
binlog-ignore-db=mysql #避免同步mysql 用戶配置,以免不必要的麻煩

slave端:
replicate_do_db=test (do這個就是直接指定的意思)

replicate_ignore_db=

MySQL 多台機器的多重 Replication 設定

MySQL 要設定 Replication 可以參考此篇: MySQL 設定 Replication (Master - Slave)
但是要設定多台機器一直持續(一層一層) Replication 下去, 預設是有無法達到的.
註:
  • Replication 從 A -> B 照上面設定即可.
  • 但是 Replication 要設定 A -> B -> C, 會發現到, A -> B 是可以動的, B -> C 也是可以動, 但是 A -> B -> C 不會動.(A -> C 的指令, 不會被傳過去)

MySQL 多台機器多重 Replication 設定方式

想要作到 A -> B -> C, 只需要於 B 的 [mysqld] 設定下述即可:
log-bin=mysql-bin
log-slave-updates

範例

[mysqld]
server-id = 1
log-bin=mysql-bin
log-slave-updates

強迫移除 MySQL Root 密碼

這是給不小心忘記 MySQL root 密碼、不小心刪掉 root 的人, 不需要因此而重灌 MySQL.(只需要依此步驟, 即可重新設定 root 密碼)
環境: Debian / Ubuntu Linux

移除 MySQL Root 密碼步驟

  1. sudo su -
  2. /etc/init.d/mysql stop
  3. /usr/sbin/mysqld --skip-grant-tables --user=root & # 啟動 MySQL
  4. mysql -u root # 已經可以不用密碼進入囉~
  5. mysql> UPDATE mysql.user SET Password=PASSWORD('') WHERE User='root'; # 將 root 密碼清掉, 或於此設定想要的密碼.
  6. mysql> quit
  7. /etc/init.d/mysql restart # 完成.

MySQL 連線認證授權步驟

MySQL 在增加 user 時, 可以使用 INSERT mysql db 或 GRANT 的方式來增加 user, 但是為何使用 grant 增加, 於 user table 的 *priv 權限值都是 N, 但是權限又是正常照設定的運作?, 到底 MySQL 連線認證是怎麼樣運作的呢?..
MySQL 連線認證授權步驟:
  • MySQL connect -> mysql db -> user table (id, password) -> db table (exec priv) -> user table(priv)
MySQL 有個 mysql 的 db, 記錄 user, db 的 table.
  1. 一個 connect 要建立, 會先檢查 user table, 看看 帳號、密碼是否正確, 正確的話, connection 正式建立.
  2. 再來是要檢查是否有執行的權限, 會再去看 db 的 table, ex: 檢查是否有 Select, Update, Insert, Delete... 等權限.
  3. 而 user table 的 *_priv等 權限, 是 db table 查不到的狀況下或其它更細節的狀況才會用到.(會發現用 grant 授權的, user table 的 *_priv 等 的值, 都會是 N)
MySQL 要特別注意 要設定哪些IP 可以連進來時, 要注意不能重覆設定(除了本機外).
假設本機 IP 是 1.1.1.1, 本機要設定 localhost 和 1.1.1.1 的那個帳號可以連進來, 不然 mysql -u id -p -h hostname 會連不進去. 但是若其它外部連過來的機器(ex: 2.2.2.2), 只能設1組IP設定, ex: 2.2.2.% 或 2.2.2.2, 這兩個只能有一個存在, 若設 domain, 也要注意 domain 反解回來的 IP 有沒有跟這IP 重覆, IP 重覆在平常運作下是不會有問題, 但是在量大的狀況下, 就會發生有些 connect 會 Access denied 的狀況.

MySQL Replication Status

  • show master status
  • show slave status
以下是 Master 機器上, show master status 出來的 欄位 和 說明:
  • Master_Host: dbm1.domain_name
  • Master_User: repl
  • Master_Port: 3306
  • Connect_retry: 60 , 這個 mysql server 重啟動到現在已經 connect 幾次了(自己 restart 會歸零)
  • Master_Log_File: dbm1-bin.009 , 目前 Master 上已經寫到第幾個了
  • Read_Master_Log_Pos: 991863990 , Slave讀到 Master 這個 log file 的第幾筆了(master 上的 file)
  • Relay_Log_File: dbs1-relay-bin.008 , Slave目前正在寫入的 binary log (slave 上的 file)
  • Relay_Log_Pos: 303654057 , 寫到第幾筆了
  • Relay_Master_Log_File: dbm1-bin.009 , Slave目前傳到 Master 上的第幾個(目前正在抓哪一個過來), 目前 Master上, 已經讀到哪個 log file(relication) binary log(一堆 SQL 指令執行的記錄, 可用 mysqlbinlog 讀取)
  • Slave_IO_Running: Yes , 這個 process 有在 run(抓 binary log), 抓 log 回來 (No: 可能原因有 網路斷, 權限問題, master stop)
  • Slave_SQL_Running: Yes , 是否有在執行 binary log (error)
  • Replicate_do_db:
  • Replicate_ignore_db:
  • Last_errno: 0 , 停掉前發生什麼事情, error number, 可用 perror 查詢
  • Last_error: (error message)
  • Skip_counter: 0 (set db slave skip counter = 1, start slave) 跳過這一筆
  • Exec_master_log_pos: 991863990 (要與 Read_Master_Log_Pos 一樣, 代表沒有 delay)
  • Relay_log_space: 303654057 目前有多少空間可以寫
平常最主要就是看 Slave_IO_Running, Slave_SQL_Running 是否是 Yes, 是 Yes 的話, 應該就都是正常在跑的狀況, 若是 No 的話, 就去看一下 Last_error 

MySQL 快速為線上運作的 Master 增加 SLAVE(設定 Replication)

操作步驟

  1. ssh master.hostname # 先設 MASTER
  2. $ mysql -u root
  3. mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY 'repl_password'; # 先假設 帳號 repl, 密碼 repl_password
  4. mysql> FLUSH TABLES WITH READ LOCK;
  5. mysql> quit
  6. $ mysqldump -u root DATABASE_NAME --master-data > DATABASE_NAME.sql
    # 若不加 --master-data, 就需要用 show master status 來記下要組合出下述語法:
    # CHANGE MASTER TO MASTER_HOST='MASTER_HOSTNAME', MASTER_USER='repl', MASTER_PASSWORD='repl_passord', MASTER_LOG_FILE='mysql-bin.000014', MASTER_LOG_POS=232;
  7. $ mysql -u root
  8. mysql> UNLOCK TABLES;
  9. mysql> quit
  10. # 到此 MASTER 設定就算完工, 也已經恢復上線了, 再下來就是 SLAVE 囉~
  11. ssh slave.hostname
  12. $ scp master.hostname:DATABASE_NAME.sql
  13. $ mysql -u root
  14. mysql> CREATE DATABASE DATABASE_NAME;
  15. mysql> use DATABASE_NAME;
  16. mysql> source DATABASE_NAME.sql;
    # 因為上述有加入 --master-data 的命令, 所以 CHANGE MASTER 等, 已經有自動加在檔案的開頭, 不過此 CHANGE MASTER 並沒有寫 MASTER 主機的資訊, 所以可於下述 /etc/my.cnf 設定, 或者去修改 DATABASE_NAME.sql, 將 CHANGE MASTER 加入主機資訊. (在此採用修改 /etc/my.cnf 的作法)
  17. mysql> quit
  18. $ vim /etc/my.cnf
    log-bin=mysql-bin
    server-id   = 3
    master-host     =   MASTER_DB.HOSTNAME
    master-user     =   repl
    master-password =   repl_password
    master-port     =  3306
  19. $ sudo /usr/local/etc/rc.d/mysql-server restart # BSD 預設路徑
  20. $ mysql -u root
  21. mysql> start slave;
  22. mysql> show slave status \G
會看到若 MASTER 有增加資料, Exec_Master_Log_Pos 這個值就會跟著增加. (Exec_Master_Log_Pos: 執行 MASTER LOG 的 POSITION), 在此任何 MASTER 的 新增/修改 都應該會自動 replication 過來 SLAVE 囉~ (中間中斷的時間, 資料也會自動補上, 因為 --master-data 已經將當時的 POSITION 記下來了, 只要倒回去, 就會自動將資料補回來)
註: 如果有完整的 mysql bin log 的話, 可以直接設好 replication 即可, 就會自動開始從 binlog 最前面開始抓, 連停機都不用