方案一:兩邊做主從。 SELECT SUM(DATA_LENGTH)+SUM(INDEX_LENGTH) FROM information_schema.tables WHERE TABLE_SCHEMA='(數據庫名大小為K除去1048576為M)';查看庫容量
SELECT TABLE_NAME,DATA_LENGTH+INDEX_LENGTH,TABLE_ROWS FROM information_schema.tables WHERE TABLE_SCHEMA='' AND TABLE_NAME='';
lqc_msg = 16651450340 =15,880M 導出來13G 16708081764
SHOW TABLE STATUS; 查看自增IP
導出數據庫: mysqldump -uroot -p'' --single-transaction --events --triggers --routines --flush-logs --master-data=2 --databases | gzip > /mnt/l.sql.gz
復制數據 rsync -a /mnt/lqc_msg.sql.gz root@:/data/
導入數據庫: mysqldump -uroot -p data < /data/lqc.sql &
SELECT SUM(DATA_LENGTH)+SUM(INDEX_LENGTH) FROM information_schema.tables WHERE TABLE_SCHEMA='lqc'
grep -i "change master" lqc.sql
開始主從同步 stop slave change master to master_host='',master_user='',master_password='',master_log_file='mysql-bin.000002',master_log_pos=107; start slave;
show slave status\G;
主從報錯;
vi /etc/my.cnf [mysqld] #slave-skip-errors=1062,1053,1146 #跳過指定error no類型的錯誤 #slave-skip-errors=all #跳過所有錯誤
1.跳過指定數量的事務: mysql>slave stop; mysql>SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1 #跳過一個事務 mysql>slave start
SELECT TABLE_NAME,DATA_LENGTH+INDEX_LENGTH,TABLE_ROWS FROM information_schema.tables WHERE TABLE_SCHEMA='lqc_msg' AND TABLE_NAME='ecm_easemob_message'; mysql> SELECT TABLE_NAME,DATA_LENGTH+INDEX_LENGTH,TABLE_ROWS FROM information_schema.tables WHERE TABLE_SCHEMA='lqc_msg' AND TABLE_NAME='ecm_easemob_message'; +---------------------+--------------------------+------------+ | TABLE_NAME | DATA_LENGTH+INDEX_LENGTH | TABLE_ROWS | +---------------------+--------------------------+------------+ | ecm_easemob_message | 9751330816 | 8283701 | +---------------------+--------------------------+------------+ row in set (0.08 sec) ecm_easemob_message 9743584 ecm_easemob_message_offline 10128638 ecm_notice_queue lq_hx_message_log 527
alter table msg_group_notice_relations AUTO_INCREMENT=100001;
alter table msg_hx_group AUTO_INCREMENT=100120; alter table msg_hx_group_member AUTO_INCREMENT=105919; alter table msg_hx_group_notice AUTO_INCREMENT=100072;
insert into t_user(id, username) values(10, "hehehe"); delete from tablename where
方案二:提高自增ID遷移。
先把表結構拷貝過去: 查看表自增ID:select max(id) from ecm_easemob_message 設置新的位+10萬,然后連接遷移過去:alter table msg_group_notice_relations AUTO_INCREMENT=100001; 插入數據測試:insert into t_user(id, username) values(10, "hehehe"); 然后遷移過去,再把舊的數據導入。
在主服務器上為從服務器建立一個用戶:
grant replication slave on *.* to '用戶名'@'主機' identified by '密碼';
如果使用的是MySQL 4.0.2之前的版本,則用file權限來代替replication slave
編輯主服務器的配置文件:/etc/my.cnf
server-id=1
log-bin
binlog-do-db=需要復制的數據庫名,如果復制多個數據庫,重復設置這個選項即可
binlog-ignore-db=不需要復制的數據庫苦命,如果復制多個數據庫,重復設置這個選項即可
注意:如果你想做一個復雜點的結構:比如說,A->B->C,其中B是A的從服務器,同時B又是C的主服務器,那么B服務器除了需要打開log-bin之外,還需要打開log-slave-updates選項,你可以再B上使用“show variables like 'log%';”來確認是否已經生效。
編輯從服務器的配置文件:/etc/my.cnf
server-id=2
master-host=主機
master-user=用戶名
master-password=密碼
master-port=端口
replicate-do-db=需要復制的數據庫名,如果復制多個數據庫,重復設置這個選項即可
replicate-ignore-db=不需要復制的數據庫名,如果復制多個數據庫,重復設置這個選項即可
配置主從服務器的my.cnf時,留心各自的server-id一定要彼此獨立,不能重復,否則,會出現如下錯誤:
Slave: received end packet FROM server, apparent master shutdown
另一個需要注意的是最好在從服務器的my.cnf里設置read_only選項,防止發生意外(連接用戶不能有SUPER權限,否則無效)。
記得先手動同步一下主從服務器,數據量小的話可以用mysqldump,它有一個master-data參數很有用,通過使用此參數,導出的SQL文件里會自動包含CHANGE MASTER TO MASTER_LOG_FILE='...', MASTER_LOG_POS=...;,這樣創建從服務器就更方便了。
如果數據量大的話不太適合使用mysqldump(慢),如果是myisam表的話,加上--lock-all-tables參數,如果是innodb表的話,加上--single-transaction參數。
而應該采用拷貝文件的方式,請按如下操作步驟:
先在主服務器上鎖定所有的表,以免在復制過程中數據發生變化:
mysql> flush tables with read lock;
然后在主服務器上查詢當前二進制文件的文件名及偏移位置:
mysql > show master status;
然后停止主服務器上的MySQL服務:
shell> mysqladmin -u root shutdown
注意:如果僅是MyISAM的話,可以不停止MySQL服務,但要在復制數據文件的過程中保持只讀鎖,如果是InnoDB的話,必須停止MySQL服務。
再拷貝數據文件:
shell> tar -cvf /tmp/mysql-snapshot.tar .
拷貝完別忘了啟動主服務上的MySQL服務了。
然后把數據文件應用到從服務器上,再次啟動slave的時候使用,記得啟動時加上skip-slave-start選項,使之不會立刻去連接master,再在從服務器上設置相關的二進制日志信息:
mysql> CHANGE MASTER TO
-> MASTER_HOST='master_host_name',
-> MASTER_USER='replication_user_name',
-> MASTER_PASSWORD='replication_password',
-> MASTER_LOG_FILE='recorded_log_file_name',
-> MASTER_LOG_POS=recorded_log_position;
啟動從服務器上的復制線程:
mysql> start slave;
驗證主從設置是否已經成功,可以輸入如下命令:
mysql> show slave status\G
會得到類似下面的列表:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
如果這兩個選項不全是Yes,那就說明你前面某個步驟配置錯了。
應該保證從服務器上任何數據的修改都是通過從主服務器上復制操作獲取的,換句話說,從服務器應該是只讀的,如果不能保證這一點,則可能造成主從數據不一致。可以在從服務器的my.cnf里加入read-only參數來實現這一點,唯一需要注意的一點事read-only僅對沒有super權限的用戶有效。所以最好核對一下連接從服務器的用戶,確保其沒有super權限。
從理想角度看,主從數據庫應該無故障的運轉下去,可以有時候還是會出現一些莫名其妙的問題,比如說即便從未在從服務器上手動更新過數據,但還是可能遇到“Error: 1062 Duplicate entry”錯誤,具體原因不詳,可能是MySQL本身的問題。遇到這類問題的時候,從服務器會停止復制操作,我們只能手動解決問題,具體的操作步驟如下:
mysql> set global sql_slave_skip_counter = 1;
mysql> start slave;
同樣的操作可能需要進行多次,也可以設置自動處理此類操作,在從服務器的my.cnf里設置:
slave-skip-errors=1062
最后再嘮叨一下日志的問題:時間長了,數據庫服務器上的二進制文件會越來越多,清理是必要的,你可以設置自動清理,相關參數是expire_logs_days,也可以使用手動刪除的方式,但這里說的手動不是指rm,而是指PURGE BINARY LOGS,刪除任何日志前,最好在所有的從服務器上通過show slave status命令確認一下相關日志是否已經無用。
更詳細的介紹參考官方文檔:How to Set Up Replication,不喜歡英文的話可以看老葉同志的中文翻譯。
補充:[ERROR] Error in Log_event::read_log_event(): 'Event too big'
在使用主從復制的時候,出現的問題多半是和日志(主服務器的二進制日志,從服務器的延遲日志)相關的。比如說加入你遇到了上面的錯誤,你可以根據錯誤日志的信息在主從數據庫服務器上分別執行:
mysqlbinlog 日志文件 > /dev/null
查看錯誤,如果沒有錯誤,則不會有任何輸出,反之會輸出錯誤信息,如果確定了錯誤是出現在主服務器二進制日志上,可以跳過適當的位置,再在從服務器上重新設定LOG_POS,如果確定了錯誤是出現在從服務器延遲日志上,則可以刪除從服務器的延遲日志(使用CHANGE TO MASTER的時候,除非設定了延遲日志信息,否則會自動刪除延遲日志),並在從服務器上重新設定LOG_POS。期間也可以考慮手動執行不能自動執行的SQL日志。
補充:配置的時候如果版本允許最好打開sync_binlog選項。
補充:有時候,從服務器延遲日志可能已經損壞,這時需要執行CHANGE MASTER TO設置新的日志文件信息,但是在從服務器上SHOW SLAVE STATUS會顯示很多日志信息,他們的含義有所不同:
Master_Log_File:Read_Master_Log_Pos 是IO相關的日志信息
Relay_Master_Log_File:Exec_Master_Log_Pos 是SQL相關的日志信息
從服務器需要設置的是SQL相關的日志信息:
slave stop;
change master to master_log_file=’(binlog name in relay_master_log_file)’, master_log_pos=(exec_master_log_pos number);
slave start;
1) When you are using the master as a consistent snapshot, use SHOW MASTER STATUS to determine the position.
2) When you are using a slave as a consistent snapshot, use SHOW SLAVE STATUS and Exec_Master_Log_Pos.
https://my.oschina.net/u/1036767/blog/207301