Mysql主從又叫Replication,AB複製。A、B兩臺機器作主從後,A上寫數據,B上也會跟着寫數據,A和B的數據實時同步。mysql
Mysql的主從實現是基於binlog的,要開啓binlog纔可以實現主從功能。linux
Mysql主從的原理:3個步驟web
一、主將更改操做記錄到binlog裏。 二、從將主的binlog事件(sql語句)同步到從的機器上,並記錄在relaylog裏(中繼日誌)。 三、根據relaylog裏的sql語句,按順序執行。 主上有一個logdump線程,用來與從的I/O線程傳遞binlog。 從上有兩個線程,其中I/O線程用來同步主的binlog並生成relaylog,另外一個線程是SQL線程把relaylog的SQL語句執行落地。
使用場景:sql
一、單獨的數據備份:主機器宕機後,備份的從機器能夠給Web服務提供數據 二、讀備份庫:web服務從主上讀寫數據,當主機器訪問壓力大的時候,能夠在從上讀數據,緩解主壓力,可是從機器不寫入數據。
主機器A、從機器B上都安裝Mysql:二進制免編譯包安裝bootstrap
一、解壓,初始化mysql:vim
[root@lgs-02 src]# tar zxvf mysql-5.6.36-linux-glibc2.5-x86_64.tar.gz mysql-5.6.36-linux-glibc2.5-x86_64/sql-bench/limits/oracle.cfg mysql-5.6.36-linux-glibc2.5-x86_64/sql-bench/limits/mysql.cfg mysql-5.6.36-linux-glibc2.5-x86_64/sql-bench/limits/Adabas.cfg mysql-5.6.36-linux-glibc2.5-x86_64/sql-bench/limits/empress.cfg mysql-5.6.36-linux-glibc2.5-x86_64/sql-bench/limits/mysql-4.0.cfg mysql-5.6.36-linux-glibc2.5-x86_64/sql-bench/limits/interbase.cfg [root@lgs-02 src]# ls mysql-5.6.36-linux-glibc2.5-x86_64 mysql-5.6.36-linux-glibc2.5-x86_64.tar.gz [root@lgs-02 mysql]# ./scripts/mysql_install_db --user=mysql --datadir=/data/mysql/ Installing MySQL system tables...2018-05-23 18:44:50 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details). 2018-05-23 18:44:50 0 [Note] Ignoring --secure-file-priv value as server is running with --bootstrap. 2018-05-23 18:44:50 0 [Note] ./bin/mysqld (mysqld 5.6.36) starting as process 1462 ... 2018-05-23 18:44:50 1462 [Note] InnoDB: Using atomics to ref count buffer pool pages 2018-05-23 18:45:07 1462 [Note] InnoDB: Shutdown completed; log sequence number 1625977 OK Filling help tables...2018-05-23 18:45:07 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details). 2018-05-23 18:45:07 0 [Note] Ignoring --secure-file-priv value as server is running with --bootstrap. 2018-05-23 18:45:07 0 [Note] ./bin/mysqld (mysqld 5.6.36) starting as process 1484 ... 2018-05-23 18:45:07 1484 [Note] InnoDB: Using atomics to ref count buffer pool pages 2018-05-23 18:45:07 1484 [Note] InnoDB: The InnoDB memory heap is disabled 2018-05-23 18:45:07 1484 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins 2018-05-23 18:45:07 1484 [Note] InnoDB: Memory barrier is not used 2018-05-23 18:45:07 1484 [Note] InnoDB: Compressed tables use zlib 1.2.3 2018-05-23 18:45:07 1484 [Note] InnoDB: Using Linux native AIO 2018-05-23 18:45:07 1484 [Note] InnoDB: Using CPU crc32 instructions 2018-05-23 18:45:07 1484 [Note] InnoDB: Initializing buffer pool, size = 128.0M 2018-05-23 18:45:07 1484 [Note] InnoDB: Completed initialization of buffer pool 2018-05-23 18:45:07 1484 [Note] InnoDB: Highest supported file format is Barracuda. 2018-05-23 18:45:07 1484 [Note] InnoDB: 128 rollback segment(s) are active. 2018-05-23 18:45:07 1484 [Note] InnoDB: Waiting for purge to start 2018-05-23 18:45:07 1484 [Note] InnoDB: 5.6.36 started; log sequence number 1625977 2018-05-23 18:45:07 1484 [Note] Binlog end 2018-05-23 18:45:07 1484 [Note] InnoDB: FTS optimize thread exiting. 2018-05-23 18:45:07 1484 [Note] InnoDB: Starting shutdown... 2018-05-23 18:45:09 1484 [Note] InnoDB: Shutdown completed; log sequence number 1625987 OK To start mysqld at boot time you have to copy support-files/mysql.server to the right place for your system PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER ! To do so, start the server, then issue the following commands: ./bin/mysqladmin -u root password 'new-password' ./bin/mysqladmin -u root -h lgs-02 password 'new-password'
二、啓動mysqld服務,啓動前:修改my.cnf配置文件的basedir、datadir,拷貝啓動腳本(也要改腳本的basedir、datadir)oracle
[root@lgs-02 mysql]# ls support-files/my-default.cnf support-files/my-default.cnf [root@lgs-02 mysql]# cp support-files/my-default.cnf /etc/my.cnf cp:是否覆蓋"/etc/my.cnf"? y [root@lgs-02 ~]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld [root@lgs-02 ~]# ls -l /etc/init.d/mysqld -rwxr-xr-x. 1 root root 10565 5月 23 19:23 /etc/init.d/mysqld [root@lgs-02 ~]# vim !$ vim /etc/init.d/mysqld basedir=/usr/local/mysql/ datadir=/data/mysql/ [root@lgs-02 ~]# /etc/init.d/mysqld start Starting MySQL.Logging to '/data/mysql/lgs-02.err'. ............ SUCCESS!
一、修改my.cnf:設置服務id、定義binlog日誌名字,重啓mysqldide
[root@lgs local]# vim /etc/my.cnf log_bin=lgs01 //binlog日誌文件的前綴,在/data/mysql/目錄下生成 lgs01.index和lgs01.000001 server_id =130 [root@lgs local]# /etc/init.d/mysqld restart Shutting down MySQL.. SUCCESS! Starting MySQL. SUCCESS!
二、建立一個庫,恢復填充數據進去用做實驗:zc01庫測試
[root@lgs tmp]# mysqldump -uroot -p7826078 zrlog >/tmp/blog.sql //備份zrlog庫到 /tmp/目錄下 Warning: Using a password on the command line interface can be insecure. [root@lgs tmp]# mysql -uroot -p7826078 -e "create database zc01" //建立zc01的庫,用做實驗 Warning: Using a password on the command line interface can be insecure. [root@lgs tmp]# mysql -uroot -p7826078 zc01 </tmp/blog.sql //用備份的blog庫文件的數據,恢復到zc01庫中。 Warning: Using a password on the command line interface can be insecure. mysql> use zc01; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +----------------+ | Tables_in_zc01 | +----------------+ | comment | | link | | log | | lognav | | plugin | | tag | | type | | user | | website | +----------------+ 9 rows in set (0.00 sec)
三、建立同步數據的用戶:replui
mysql> grant replication slave on *.* to 'repl'@'192.168.87.132' identified by '7826078'; //指定來源ip的從機器的ip。 Query OK, 0 rows affected (0.00 sec) mysql> flush tables with read lock; //鎖表,不讓繼續寫數據 Query OK, 0 rows affected (0.02 sec) mysql> show master status; //記住file和Position的內容,從機器配置的時候要用到。 +--------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +--------------+----------+--------------+------------------+-------------------+ | lgs01.000001 | 35637 | | | | +--------------+----------+--------------+------------------+-------------------+ 1 row in set (0.01 sec) [root@lgs tmp]# ls -l /data/mysql/ //主機器上的庫文件,一會同步zc01庫。 總用量 110820 -rw-rw----. 1 mysql mysql 56 4月 17 18:58 auto.cnf -rw-rw----. 1 mysql mysql 12582912 6月 28 23:27 ibdata1 -rw-rw----. 1 mysql mysql 50331648 6月 28 23:27 ib_logfile0 -rw-rw----. 1 mysql mysql 50331648 4月 17 18:47 ib_logfile1 -rw-rw---- 1 mysql mysql 35637 6月 28 23:43 lgs01.000001 -rw-rw----. 1 mysql mysql 130455 5月 10 08:12 lgs-01.err -rw-rw---- 1 mysql mysql 15 6月 28 22:16 lgs01.index -rw-rw---- 1 mysql mysql 43229 6月 28 22:16 lgs.err -rw-rw---- 1 mysql mysql 5 6月 28 22:16 lgs.pid drwx------. 2 mysql mysql 4096 4月 17 18:47 mysql drwx------. 2 mysql mysql 4096 4月 17 18:47 performance_schema drwx------. 2 mysql mysql 6 4月 17 18:47 test drwx------ 2 mysql mysql 324 6月 28 23:27 zc01
四、備份zc01庫文件,拷貝到從機器上去:在從上新建庫,用zc01庫文件數據恢復到新建的庫中去。
[root@lgs tmp]# mysqldump -uroot -p7826078 zc01 >/tmp/zc01.sql Warning: Using a password on the command line interface can be insecure. [root@lgs tmp]# ls -l zc01.sql -rw-r--r-- 1 root root 34508 6月 28 23:51 zc01.sql
一、修改my.cnf文件:設置服務id,與主的服務id不同。重啓mysqld
[root@lgs-02 tmp]# vim /etc/my.cnf [mysqld] server_id =131 [root@lgs-02 tmp]# /etc/init.d/mysqld restart Shutting down MySQL.. SUCCESS! Starting MySQL. SUCCESS!
二、把主上的zc01.sql庫文件拷貝到從上:放/tmp/目錄下
三、建立一個庫,把zc01的數據恢復進去
mysql> create database zc01; //建立新庫zc01 Query OK, 1 row affected (0.00 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | | zc01 | +--------------------+ 5 rows in set (0.01 sec) mysql> quit Bye [root@lgs-02 tmp]# mysql -uroot -p7826078 zc01 </tmp/zc01.sql //恢復主上拷貝過來的庫數據到從上的zc01庫 Warning: Using a password on the command line interface can be insecure.
四、實現主從:
mysql> stop slave; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> change master to master_host='192.168.87.130',master_user='repl',master_password='7826078',master_log_file='lgs01.000001',master_log_pos=35637; //配置主信息 Query OK, 0 rows affected, 2 warnings (0.05 sec) mysql> start slave; //打開主從同步 Query OK, 0 rows affected (0.02 sec)
五、檢測是否成功配置主從:Slave_IO_Running: Yes和Slave_SQL_Running: Yes 就表明成功配置
mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.87.130 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: lgs01.000001 Read_Master_Log_Pos: 35637 Relay_Log_File: lgs-02-relay-bin.000003 Relay_Log_Pos: 279 Relay_Master_Log_File: lgs01.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 35637 Relay_Log_Space: 612 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 130 Master_UUID: 40e65727-422e-11e8-8d14-000c29d0e2b8 Master_Info_File: /data/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 1 row in set (0.00 sec)
若是Slave_IO_Running: Connectting. 把主上的firewalld、selinux關掉再打開同步。
六、主機器上:解鎖表。
mysql> unlock tables; Query OK, 0 rows affected (0.01 sec)
七、關注這些主從的狀態:
Seconds_Behind_Master: 0 //延時 Last_IO_Errno: 0 //io線程錯誤 Last_IO_Error: Last_SQL_Errno: 0 //執行sql錯誤 Last_SQL_Error:
主機器上寫入數據,看可否同步到從機器上。
測試前,能夠自定義幾個主從相關的參數:my.cnf
## 主機器上的配置 [root@lgs tmp]# vim /etc/my.cnf [mysqld] binlog_do_db= //僅同步指定的庫,多個庫用逗號分隔 binlog_ignore_db= //忽略指定庫,剩餘的都同步。
##從機器上的配置 Replicate_do_db= Replicate_ignore_db= Replicate_do_table= Replicate_ignore_table= Replicate_wild_do_table= Replicate_wild_ignore_table=
開始測試:
##主上 mysql> use zc01; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +----------------+ | Tables_in_zc01 | +----------------+ | comment | | link | | log | | lognav | | plugin | | tag | | type | | user | | website | +----------------+ 9 rows in set (0.00 sec) mysql> select count(*) user; +------+ | user | +------+ | 1 | +------+ 1 row in set (0.01 sec) mysql> select count(*) comment; +---------+ | comment | +---------+ | 1 | +---------+ 1 row in set (0.00 sec) ##從上 mysql> use zc01; Database changed mysql> show tables; +----------------+ | Tables_in_zc01 | +----------------+ | comment | | link | | log | | lognav | | plugin | | tag | | type | | user | | website | +----------------+ 9 rows in set (0.00 sec) mysql> select count(*) user; +------+ | user | +------+ | 1 | +------+ 1 row in set (0.01 sec) mysql> select count(*) comment; +---------+ | comment | +---------+ | 1 | +---------+ 1 row in set (0.00 sec) mysql> select count(*) website; +---------+ | website | +---------+ | 1 | +---------+ 1 row in set (0.01 sec)
主上刪除comment表的數據:再看看從的comment表是否也會0行
mysql> drop table comment; Query OK, 0 rows affected (0.02 sec) mysql> show tables; +----------------+ | Tables_in_zc01 | +----------------+ | link | | log | | lognav | | plugin | | tag | | type | | user | | website | +----------------+ 8 rows in set (0.00 sec)
從上查詢comment表的時候就報錯不存在表了:證實從上同步主的操做了。
mysql> select * from comment; ERROR 1146 (42S02): Table 'zc01.comment' doesn't exist