MySQL日誌及主從複製實現

MySQL日誌及主從複製實現mysql

 

一:MySQL是一個關係型數據庫管理系統,最先由瑞典MySQL AB 公司發,後在2008年1月16號被Sun公司用10億美金收購,但好景不長,2010年4月20日oracle用74億美金收購了Sun,所以到目前MySQL屬於 Oracle旗下產品。MySQL 最流行的關係型數據庫管理系統,在 WEB 應用方面MySQL是最好的 RDBMS (Relational Database Management System,關係數據庫管理系統) 應用軟件之一,MySQL是一種關聯數據庫管理系統,關聯數據庫將數據保存在不一樣的表中,而不是將全部數據放在一個大倉庫內,這樣就增長了速度並提升了靈活性。
MySQL所使用的 SQL 語言是用於訪問數據庫的最經常使用標準化語言。MySQL 軟件採用了雙受權政策,它分爲社區版和商業版,因爲其體積小、速度快、整體擁有成本低,尤爲是開放源碼這一特色,通常中小型網站的開發都選擇 MySQL 做爲網站數據庫,因爲其社區版的性能卓越,搭配 PHP 和 Apache 可組成良好的開發環境。
linux

1.1:MySQL主從複製過程:

    MySQL主從同步一共須要三個線程的操做,主MySQL有一個IO線程,從MySQL有一個IO線程和一個SQL線程, MySQL主從是實現MySQL高可用、數據備份、讀寫分離架構的一種最多見的解決方案,在絕大部分公司都有使用,要實現MySQL主從複製,必需要在Master打開binary log(bin-log)功能,由於整個MySQL的複製過程實際就是Slave從Master端獲取響應的二進制日誌,而後在Slave端順序的執行日誌中所記錄的各類操做,二進制日誌中幾乎記錄了出select之外的全部針對數據庫的sql操做語句,具體的複製過程以下: sql

1.1.1:Slave端的IO線程鏈接上Master,並向Master請求指定日誌文件的指定位置(新部署的Master和Slave從最開始的日誌)以後的日誌。 數據庫

1.1.2:Master接收到來自Slave的IO線程請求,負責IO複製的IO線程根據Slave的請求信息讀取相應的日誌內容,而後將本地讀取的bin-log的文件名、位置及指定位置以後的內容一塊兒返回給Slave的IO線程處理。 vim

1.1.3:Slave的IO線程將接收到的信息依次添加到Slave端的relay-log文件的最末端,並將讀取到的Master端的bin-log的文件名和位置記錄到Master-info文件中,以便在下一次讀取的時候可以清楚的告訴Master「我須要從哪一個bin-log的哪一個位置開始日後的日誌內容請發給我」。 bash

1.1.4:Slave的sql線程檢查到relay-log中新增了內容後,會立刻將relay-log中的內容解析爲在Master端真實執行時候的可執行命令,並順序執行,從而保證對Slave的MySQL進行響應的增長或刪除等操做,最終實現和Master數據保持一致。 服務器

1.2:減小主從同步延時的方案: 網絡

1.2.1:從庫使用SSD硬盤,這樣從庫能夠用最快的速度從主控同步數據 多線程

1.2.2:儘可能在主庫使用避免大量的寫入,可使用其餘非關係型數據庫的儘可能使用非關係型數據庫 架構

1.2.3:主庫和從庫直接使用專用網絡高速互聯

1.2.4:對於數據一致性要求比較嚴格的場景,就不查詢從庫,由於從庫可能有數據未同步到數據

1.2.5:讀場景比較大的場景,可使用多個從庫,將讀請求在各個slave服務器分解處理

1.3:數據庫延遲複製,即設置slave故意從master延遲同步一小時或其餘指定時間差,用於解決一下三個問題:

1.3.1:用於在數據庫誤操做以後快速的恢復數據,好比誤刪除表,那個這個延遲操做在延遲時間內從庫的數據尚未發生變化,可使用從庫的數據進行恢復,而後再把一小時內的bin-log補寫到Master便可完成數據的所有恢復。

1.3.2:用來作延遲測試,好比作好的數據庫讀寫分離,把從庫做爲讀庫,即測試主從數據延遲五分鐘或指定的時候,業務會發生什麼樣的問題,便可以模擬數據庫延遲指定時間的業務錯誤。

1.3.3:用於老數據的查詢,好比常常須要查看某天前的一個表或者字段的數值,你可能須要把備份恢復以後才能進行查看,可是若是有延遲從庫,好比延遲一週,那麼久能夠解決這一的相似的業務需求場景。

1.3.4:設置延遲複製,經過設置SLAVE上的MASTER TO MASTER_DELAY參數來實現:

CHANGE MASTER TO MASTER_DELAY = N;

N爲多少秒,該語句設置從庫延時N秒後再與主數據庫進行同步複製

1.3.5:具體MySQL延遲複製操做,登陸到SLAVE之上進行操做:

mysql> stop slave; mysql> CHANGE MASTER TO MASTER_DELAY = 600; mysql> start slave; mysql> SHOW SLAVE STATUS \G;

1.4:生產環境MySQL經驗:

1.4.1:生產應用MySQL用戶,不容許執行delete,能夠只受權給update、select、insert,能夠把delete更改成update,將要刪除的數據加一個字段標記爲已刪除,所以線上的業務能夠不須要delete

1.4.2:在有條件的狀況下作一個延遲一小時等制定時間的從庫

1.4.3:全部DML操做以前必須備份

1.4.4:規範開發在update數據庫必須有兩個腳本,以下:

1.4.4.1:數據庫修改腳本,修改數據庫的腳本

1.4.4.2:數據庫回滾腳本,當數據更新失敗的時候用於回滾

1.5:DML操做備份腳本

dml_backup.sh  stable_name  #輸入代表便可備份表

1.5.1:開啓相關日誌:

 

[mysqld] socket=/var/lib/mysql/mysql.sock user=mysql symbolic-links=0 datadir=/data/mysql innodb_file_per_table=1 relay-log = /data/mysql server-id=20 log-error= /data/mysql_error.txt #記錄錯誤日誌 log-bin=/data/mysql/master-log #MySQL的bin-log即二進制日誌,記錄二進制形式SQL語句、主從複製和增量備份使用 general_log=ON #正常查詢日誌 general_log_file=/data/general_mysql.log long_query_time=2 #慢查詢日誌配置 slow_query_log=1 slow_query_log_file= /data/slow_mysql.txt [client] port=3306 socket=/var/lib/mysql/mysql.sock [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/tmp/mysql.sock

 

1.5.2:mysqlsla 工具使用:

使用語法以下:
# mysqlslap [options]
經常使用參數 [options] 詳細說明:
–auto-generate-sql, -a 自動生成測試表和數據,表示用mysqlslap工具本身生成的SQL腳原本測試併發壓力。
–auto-generate-sql-load-type=type 測試語句的類型。表明要測試的環境是讀操做仍是寫操做仍是二者混合的。取值包括:read,key,write,update和mixed(默認)。
–auto-generate-sql-add-auto-increment 表明對生成的表自動添加auto_increment列,從5.1.18版本開始支持。
–number-char-cols=N, -x N 自動生成的測試表中包含多少個字符類型的列,默認1
–number-int-cols=N, -y N 自動生成的測試表中包含多少個數字類型的列,默認1
–number-of-queries=N 總的測試查詢次數(併發客戶數×每客戶查詢次數)
–query=name,-q 使用自定義腳本執行測試,例如能夠調用自定義的一個存儲過程或者sql語句來執行測試。
–create-schema 表明自定義的測試庫名稱,測試的schema,MySQL中schema也就是database。
–commint=N 多少條DML後提交一次。
–compress, -C 若是服務器和客戶端支持都壓縮,則壓縮信息傳遞。
–concurrency=N, -c N 表示併發量,也就是模擬多少個客戶端同時執行select。可指定多個值,以逗號或者–delimiter參數指定的值作爲分隔符。例如:–concurrency=100,200,500。
–engine=engine_name, -e engine_name 表明要測試的引擎,能夠有多個,用分隔符隔開。例如:–engines=myisam,innodb。
–iterations=N, -i N 測試執行的迭代次數,表明要在不一樣併發環境下,各自運行測試多少次。
–only-print 只打印測試語句而不實際執行。
–detach=N 執行N條語句後斷開重連。
–debug-info, -T 打印內存和CPU的相關信息。

說明:
測試的過程須要生成測試表,插入測試數據,這個mysqlslap能夠自動生成,默認生成一個mysqlslap的schema,若是已經存在則先刪除。能夠用–only-print來打印實際的測試過程,整個測試完成後不會在數據庫中留下痕跡。
各類測試參數實例(-p後面跟的是mysql的root密碼):
單線程測試。測試作了什麼。
# mysqlslap -a -uroot -p123456
多線程測試。使用–concurrency來模擬併發鏈接。
# mysqlslap -a -c 100 -uroot -p123456
迭代測試。用於須要屢次執行測試獲得平均值。
# mysqlslap -a -i 10 -uroot -p123456
# mysqlslap —auto-generate-sql-add-autoincrement -a -uroot -p123456
# mysqlslap -a –auto-generate-sql-load-type=read -uroot -p123456
# mysqlslap -a –auto-generate-secondary-indexes=3 -uroot -p123456
# mysqlslap -a –auto-generate-sql-write-number=1000 -uroot -p123456
# mysqlslap –create-schema world -q 「select count(*) from City」 -uroot -p123456
# mysqlslap -a -e innodb -uroot -p123456
# mysqlslap -a –number-of-queries=10 -uroot -p123456
測試同時不一樣的存儲引擎的性能進行對比:
# mysqlslap -a –concurrency=50,100 –number-of-queries 1000 –iterations=5 –engine=myisam,innodb –debug-info -uroot -p123456
執行一次測試,分別50和100個併發,執行1000次總查詢:
# mysqlslap -a –concurrency=50,100 –number-of-queries 1000 –debug-info -uroot -p123456
50和100個併發分別獲得一次測試結果(Benchmark),併發數越多,執行完全部查詢的時間越長。爲了準確起見,能夠多迭代測試幾回:
# mysqlslap -a –concurrency=50,100 –number-of-queries 1000 –iterations=5 –debug-info -uroot -p123456

二:數據庫主從同步實現:

2.1:兩臺服務器分別安裝MySQL,提早準備好安裝包和my.conf文件,使用如下腳本自動安裝:

 

[root@sql-master mysql]# cat mysql-install.sh  #!/bin/bash DIR=`pwd` NAME="mysql-5.6.34-linux-glibc2.5-x86_64.tar.gz" FULL_NAME=${DIR}/${NAME} DATA_DIR="/data/mysql" yum install vim gcc gcc-c++ wget autoconf net-tools lrzsz iotop lsof iotop bash-completion -y yum install curl policycoreutils openssh-server openssh-clients postfix -y if [ -f ${FULL_NAME} ];then echo "安裝文件存在" else echo "安裝文件不存在" exit 3 fi if [ -h /usr/local/mysql ];then echo "Mysql 已經安裝" exit 3 else tar xvf ${FULL_NAME} -C /usr/local/src ln -sv /usr/local/src/mysql-5.6.34-linux-glibc2.5-x86_64 /usr/local/mysql if id mysql;then echo "mysql 用戶已經存在,跳過建立用戶過程" fi useradd mysql -s /sbin/nologin if id mysql;then chown -R mysql.mysql /usr/local/mysql/* -R if [ ! -d /data/mysql ];then mkdir -pv /data/mysql && chown -R mysql.mysql /data -R /usr/local/mysql/scripts/mysql_install_db --user=mysql --datadir=/data/mysql --basedir=/usr/local/mysql/ cp /usr/local/src/mysql-5.6.34-linux-glibc2.5-x86_64/support-files/mysql.server /etc/init.d/mysqld chmod a+x /etc/init.d/mysqld cp ${DIR}/my.cnf /etc/my.cnf ln -sv /usr/local/mysql/bin/mysql /usr/bin/mysql /etc/init.d/mysqld start else echo "MySQL數據目錄已經存在," exit 3 fi fi fi

1.2:更改Master和Slave的my.conf文件,主要將id改成不同:

1.2.1:Master的配置my.conf文件,更改完成重啓MySQL服務:

 

[root@sql-master ~]# cat /etc/my.cnf [mysqld] socket=/var/lib/mysql/mysql.sock user=mysql symbolic-links=0 datadir=/data/mysql innodb_file_per_table=1 server-id=10 log-bin=/data/mysql/master-log [client] port=3306 socket=/var/lib/mysql/mysql.sock [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/tmp/mysql.sock

1.2.2:Slave的my.cnf配置文件,更改完成重啓MySQL服務:

 

[root@sql-slave ~]# cat /etc/my.cnf [mysqld] socket=/var/lib/mysql/mysql.sock user=mysql symbolic-links=0 datadir=/data/mysql innodb_file_per_table=1 relay-log = /data/mysql #中級日誌的路徑 server-id=20 #server id與Master不能同樣 [client] port=3306 socket=/var/lib/mysql/mysql.sock [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/tmp/mysql.sock

1.2.3:在 Master生成簡單數據:

mysql> create database testdatabase; #建立庫 Query OK, 1 row affected (0.00 sec) mysql> use testdatabase; #切換庫 Database changed mysql> CREATE TABLE testtable (Id_P int,Name varchar(255),Address varchar(255),City varchar(255)); #建立表 Query OK, 0 rows affected (0.47 sec) mysql> show tables; #查看錶 +------------------------+ | Tables_in_testdatabase | +------------------------+ | testtable | +------------------------+ 1 row in set (0.01 sec) mysql> INSERT INTO testtable VALUES (1,"Jack","China","Beijing"); #插入數據 Query OK, 1 row affected (0.00 sec) mysql> select * from testtable; #插卡數據並驗證 +------+------+---------+---------+ | Id_P | Name | Address | City | +------+------+---------+---------+ | 1 | Jack | China | Beijing | +------+------+---------+---------+ 1 row in set (0.00 sec)

1.2.4:建立同步帳號:

mysql> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'tom'@'192.168.10.%' IDENTIFIED BY '123456'; #受權tom從192.168.10.*使用密碼123456同步數據 Query OK, 0 rows affected (0.30 sec)

1.2.5:Master導出數據、複製到Slave:

[root@sql-master ~]# /usr/local/mysql/bin/mysqldump --all-databases --single_transaction --flush-logs --master-data=2 --lock-tables > /backup.sql [root@sql-master ~]# scp /backup.sql 192.168.10.102:/opt/ root@192.168.10.102's password: backup.sql 100% 637KB 636.7KB/s 00:00

1.2.6:Slave將sql文件導入並記錄Master的日誌文件名稱和要同步的位置:

[root@sql-slave ~]# /usr/local/mysql/bin/mysql < /opt/backup.sql

1.2.7:在Slave配置從Master同步並設置Slave開啓 只讀:

mysql> CHANGE MASTER TO MASTER_HOST='192.168.10.101',MASTER_USER='tom',MASTER_PASSWORD='123456',MASTER_LOG_FILE='master-log.000006',MASTER_LOG_POS=120; Query OK, 0 rows affected, 2 warnings (0.01 sec) mysql> start slave; Query OK, 0 rows affected (0.00 sec) mysql> show global variables like "%read_only%"; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | innodb_read_only | OFF | | read_only | OFF | | tx_read_only | OFF | +------------------+-------+ 3 rows in set (0.00 sec) mysql> set global read_only=1; #開啓只讀模式,只讀模式僅對普通用戶生效,對root不生效 Query OK, 0 rows affected (0.00 sec) mysql> show global variables like "%read_only%"; #驗證是否生效 +------------------+-------+ | Variable_name | Value | +------------------+-------+ | innodb_read_only | OFF | | read_only | ON | | tx_read_only | OFF | +------------------+-------+ 3 rows in set (0.00 sec)

1.2.8:驗證Slave的IO線程與SQL線程是OK的:

mysql> show slave status\G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.10.101 Master_User: tom Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master-log.000006 Read_Master_Log_Pos: 120 Relay_Log_File: mysql.000002 Relay_Log_Pos: 284 Relay_Master_Log_File: master-log.000006 Slave_IO_Running: Yes #這兩個線程狀態必須爲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: 120 Relay_Log_Space: 447 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收到的bin-log到當前的同步位置差多少秒,不是嚴格意義的主從差多少秒,由於Master的bin-log更新之後可能尚未同步到Slave 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: 10 Master_UUID: 003e966d-de3e-11e6-bc0f-000c2944baf2 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)

1.2.9:關於Master_Info_File:

記錄了MySQL Master的IP地址、同步使用的用戶名和密碼、MySQL端口、bin-log日誌文件名等信息:

 

[root@sql-slave ~]# cat /data/mysql/master.info 23 master-log.000006 #Master bin-log的文件名 392 #Master的Position位置  192.168.10.101 #Master地址 tom #同步用戶 123456 #密碼 3306 #端口 60 0 0 1800.000 0 003e966d-de3e-11e6-bc0f-000c2944baf2 86400 0

1.2.10:Master信息以下:

 

mysql> show master status; +-------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------+----------+--------------+------------------+-------------------+ | master-log.000006 | 392 | | | | +-------------------+----------+--------------+------------------+-------------------+

1.2.11:

爲了保證主從同步能夠一直進行,在slave庫上要保證具備super權限的root等用戶只能在本地登陸,不會發生數據變化,其餘遠程鏈接的應用用戶只按需分配爲select,insert,update,delete等權限,保證沒有super權限,則只須要將salve設定「read_only=1」模式,便可保證主從同步,又能夠實現從庫只讀。

1.3:在Master 新插入數據,驗證是否回同步到Slave:

1.3.1:在Master插入數據:

mysql> use testdatabase; 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> INSERT INTO testtable VALUES (2,"tom","China","Beijing"); Query OK, 1 row affected (0.00 sec)

1.3.2:在Slave驗證數是否同步完成:

1.4:MySQL主從同步狀態和監控腳本:

1.4.1:腳本內容:

[root@sql-slave ~]# cat mysql_monitor.sh  #!/bin/bash Seconds_Behind_Master(){ NUM=`mysql -uroot -hlocalhost -e "show slave status\G;" | grep "Seconds_Behind_Master:" | awk -F: '{print $2}'` echo $NUM } master_slave_check(){ NUM1=`mysql -uroot -hlocalhost -e "show slave status\G;" | grep "Slave_IO_Running" | awk -F: '{print $2}' | sed 's/^[ \t]*//g'` #echo $NUM1 NUM2=`mysql -uroot -hlocalhost -e "show slave status\G;" | grep "Slave_SQL_Running:" | awk -F: '{print $2}' | sed 's/^[ \t]*//g'` #echo $NUM2 if test $NUM1 == "Yes" && test $NUM2 == "Yes";then echo 50 else echo 100 fi } main(){ case $1 in Seconds_Behind_Master) Seconds_Behind_Master; ;; master_slave_check) master_slave_check ;; esac } main $1

1.4.2:執行結果:

1.4.3:zabbix添加主從同步狀態監控並報警:

1.4.4:zabbix添加主從同步延遲並報警:

相關文章
相關標籤/搜索