MySQL和MariaDB 備份 主從 讀寫分離

查詢緩存:

如何判斷是否命中:

通過查詢語句的哈希值判斷:哈希值考慮的因素包括

查詢本身、要查詢的數據庫、客戶端使用協議版本,...

 

查詢語句任何字符上的不同,都會導致緩存不能命中;

 

哪此查詢可能不會被緩存?

查詢中包含UDF、存儲函數、用戶自定義變量、臨時表、mysql庫中系統表、或者包含列級權限的表、有着不確定值的函數(Now());

 

查詢緩存相關的服務器變量:

query_cache_min_res_unit: 查詢緩存中內存塊的最小分配單位;

較小值會減少浪費,但會導致更頻繁的內存分配操作;

較大值會帶來浪費,會導致碎片過多;

query_cache_limit:能夠緩存的最大查詢結果;

對於有着較大結果的查詢語句,建議在SELECT中使用SQL_NO_CACHE

query_cache_size:查詢緩存總共可用的內存空間;單位是字節,必須是1024的整數倍;

query_cache_type:ON, OFF, DEMAND

query_cache_wlock_invalidate:如果某表被其它的連接鎖定,是否仍然可以從查詢緩存中返回結果;默認值爲OFF,表示可以在表被其它連接淘寶的場景中繼續從緩存返回數據;ON則表示不允許;

 

查詢相關的狀態變量

SHOWGLOBAL STATUS LIKE 'Qcache%';

+-------------------------+----------+

|Variable_name           | Value    |

+-------------------------+----------+

|Qcache_free_blocks      | 1        |

|Qcache_free_memory      | 16759688 |

|Qcache_hits             | 0        |

|Qcache_inserts          | 0        |

|Qcache_lowmem_prunes    | 0        |

|Qcache_not_cached       | 0        |

|Qcache_queries_in_cache | 0        |

|Qcache_total_blocks     | 1        |

+-------------------------+----------+

 

緩存命中率的評估:Qcache_hits/(Qcache_hits+Com_select)

 

 

查詢mysql運行時全局變量

例:查詢與緩存有關的去全局變量

showglobal variables like '%query%'

select@@query_cache_type;

關閉緩存

set query_cache_type=off;

 

 

MySQL日誌:

 

是否啓用二進制日誌

sql_log_bin=on

 

二進制日誌保存位置

log-bin=二進制日誌保存位置

wKiom1WI9SOjNePxAACJz3HKOXI653.jpg

show binary logs;

wKioL1WI9vGBrRV_AACFE9kFHBI031.jpg

查看二進制日誌

showbinlog events in 'mysql-bin.000001'\G

wKiom1WI9UmhhZFWAAD2xpeK3Hs271.jpg

 

二進制日誌文件的位置:

wKioL1WI9xHBzOGyAABy0akyORQ475.jpg

 

二進制日誌保存格式

binlog_format=mixed混合|statement基於語句|row基於行

是否啓用二進制日誌

sql_log_bin=on

設置單個二進制日誌文件大小上限

max_binlog_size=1073741824 [最下4k最大1G]

設置二進制日誌緩存文件大小

max_binlog_cache_size=18446744073709547520[這個值不能大於max_binlog_stmt_cache_size]

max_binlog_stmt_cache_size=18446744073709547520

設置多久同步一次二進制日誌文件,0表示不同步,任何正值都表示記錄多少個語句後同步一次

sync_binlog=0

 

二進制日誌的格式

[root@1GPC~]# mysqlbinlog mysql-bin.000001

wKiom1WI9W_BLOP1AAF5icocyJY140.jpg

 

 

MySQL的備份和恢復

注意的要點

1.可容忍丟失多少數據

2.需要恢復什麼

3.持鎖時長

4.備份過程時長

5.備份時cpu的負載

6.恢復過程時長

備份類型:

完全備份,部分備份:僅備份其中的一張表或多張表

完全備份,增量備份:僅備份從上次完全備份或增量備份之後變化的數據部分

 

熱備份、溫備份、冷備份

熱備份:在線備份,讀寫不受影響

溫備份:在線備份,讀可進行,寫不允許

冷備份:離線備份,數據庫服務器離線,備份期間不能爲業務提供讀寫服務

 

MyISAM:溫備份

InnoDB:熱備份

 

物理備份和邏輯備份

物理備份:直接複製數據文件進行的備份。

優點:基於文件進行備份的,可以直接複製。恢復數據快。

缺點:和存儲引擎有關,MyISAM導出的數據不能導入到InnoDB中。不能跨OS

邏輯備份:從數據庫中"導出"數據另存而進行的備份。

優點:可以通過修改sql語句進行二次加工,與存儲引擎無關,可以導入到任何存儲引擎中;

缺點:無法保證數據導出和在導入或一致性,因爲浮點數會取近似值。索引需重建

 

 

設計備份方案:

備份數據、二進制日誌、InnoDB事務日誌等日誌數據、代碼(存儲過程和存儲函數、觸發器、時間調度器等)、服務器配置文件

 

完全備份+增量備份

建議完全備份1週一次,1天一次增量備份

 

使用mysqldump做完全備份,通過備份二進制日誌實現增量備份

lvm2快照:幾乎熱備,用cptar做完全備份,通過備份二進制日誌實現增量備份

xtrabackup:物理備份

InnoDB:熱備份,支持完全備份和增量備份

其他存儲引擎:溫備份

備份工具:

wKiom1WI9beiDbw1AAPkgjuDwOo786.jpg

mysqldump:邏輯備份工具,支持完全備份和部分備份,不支持增量備份,若要支持需備份二進制日誌,對其他存儲引擎溫備份,InnoDB熱備份

C/S架構,mysqldumpClientmysqldSERver

-A:備份所有數據庫例:mysqldump -A -uroot -hlocalhost -x -p > /tmp/all.sql

要用 -x 鎖定所要備份表 -l 鎖定備份的表[會導致數據不一致,最好不要使用]

--single-transaction:表示啓動一個單一事務實現備份,可以實現鎖定備份的表

-B:指定備份哪個數據庫例:mysqldump -uroot -hlocalhost -x -B test -p > /tmp/test.sql

使用-B和不使用-B直接備份數據庫是有區別的,-B會自動添加create database 數據庫這條語句,不使用則需恢復時自檢創建數據庫

備份表:mysqldump -uroot -hlocalhost mysql user -p > /tmp/mysql.test

-C:壓縮傳輸,但會大量佔用ServerCPU

-E:備份指定數據庫的事件調度器

-R:備份存儲過程和存儲函數

--triggers:備份觸發器

--master-data[=#]

0 表示不記錄

1 記錄CHANGE MASTERTO語句,此語句未被註釋

2 記錄CHANGE MASTERTO語句,此語句被註釋

例:mysqldump --master-data=2 --lock-all-tables -A > /tmp/all.1.sql

-F:鎖定表後執行flushlogs命令

 

案例:每週日完全備份,每週一到週五增量備份

二進制日誌文件與數據文件不應放在同一磁盤上

hellodb單個數據庫:在crontable中設計週期任務

完全備份:mysqldump -B tpweb --flush-logs --lock-all-tables --master-data=2 -uroot -hlocalhost -p > /tmp/tpweb-`date +%F`.sql

在這個sql文件中會看見

wKioL1WI95rS7JuyAABeysEgTsc196.jpg

22行表示備份後的所有的更改將會保存在mysql-bin.000003二進制文件中

增量備份:基於二進制日誌文件進行備份

mysqladmin-uroot -p flush-logs

這時將會產生一個新的二進制日誌文件mysql-bin.000004,mysql-bin.000003二進制文則會保存自上次備份後到現在的所有更改,只需把這個文件備份到安全的位置即可

mysqlbinlog /data/mysql-bin.000003 > /tmp/mysql-bin.000003

恢復備份:

mysql> SET SESSION sql_log_bin=0;關閉還原時產生的二進制日誌

mysql> SOURCE  /tmp/tpweb-2015-06-16.sql

mysql> SET SESSION sql_log_bin=1;恢復完成後開啓二進制日誌

不然就只能去編輯配置文件去關閉二進制日誌,用命令行還原

 

1.恢復完全備份

mysql -uroot -hlocalhost -p < /tmp/tpweb-2015-06-16.sql

2.恢復增量備份

mysql -uroot -hlocalhost -p < /tmp/mysql-bin.000003

當數據未備份卻進行了誤操作,可通過二進制日誌進行恢復

例:誤刪除了數據庫

1.備份二進制日誌文件到安全的位置上

mysqlbinlog /data/mysql-bin.000003 > /tmp/mysql-bin.000003

2.vimmysql-bin.000003

找到最近一次的誤操作並刪除,並用mysql -uroot -hlocalhost -p < /tmp/mysql-bin.000003恢復

wKiom1WI9e_zOOSqAAFZVpaB62w360.jpg

1.先用mysqlbinlog/data/mysql-bin.000003看下誤操作的position at 後面的數字

mysqlbinlog --stop-position 7295 /data/mysql-bin.000003 > /tmp/mysql-bin.000003

2.mysql -uroot -hlocalhost-p < /tmp/mysql-bin.000003

cptar等文件系統工具:物理備份工具,冷備份,一般用於MyISAM備份,支持完全備份和部分備份

lvm2快照:幾乎熱備份,藉助cptar等文件系統工具實現物理備份,需備份事務日誌

ibbackup:對於InnoDB支持熱備份,需向IBM繳費

xtrbackup:InnoDB熱備份,支持完全和增量備份

        MyISAM溫備份,只支持完全備份

 

官網下載percona-xtrabackup-2.2.3-4982.el6.x86_64.rpm

yum install yum install perl-DBD-MySQL

yuminstall percona-xtrabackup-2.2.3-4982.el6.x86_64.rpm

 

 

MySQL複製

複製功用

數據分佈、負載均衡、備份、高可用和故障切換、MySQL升級測試,

要想實現複製,需在主節點開啓二進制日誌

 

主從複製:

從服務器:

I/O線程:從master請求二進制日誌信息,並保存至slave中繼日誌

SQL線程:從[relay log]中繼日誌中讀取日誌信息,在本地完成重放

 

默認工作在異步[async]模式

 

存在的問題:

1.主從數據不一致

2.從服務器數據落後主服務器

 

雙主模型:

讀:負載均衡

寫:都要寫入,無法均衡

 

複製時應注意的問題

1.主節點運行很久後要加入從節點

在主節點上做一個完全備份,並記錄二進制日誌文件及position位置

在從節點恢復此完全備份,並在啓動複製是從記錄的二進制日誌文件position位置開始

 

2.如何限制從服務器只讀

在從服務器啓動read_only:但僅對非具有SUPER權限的用戶有效

阻止所有用戶:MariaDB> flush tables with read lock

 

3.如何保證主從複製時事務安全

master節點上啓用參數:

sync_binlog=on

若用到的爲InnoDB存儲引擎:

啓用Innodb_flush_logs_at_trx_commit  表示一旦提交了事務立即同步到磁盤上

Innodb_support_xa=on

slave節點上:

skip_slave_start=on  表示跳過slave自動啓動

主節點在不考慮磁盤IO的情況下:

snyc_master_info=1

從節點在不考慮磁盤IO的情況下:

snyc_master_info=1

snyc_relay_log=1

sync_relay_log_info=1

 

3.爲了避免從服務器數據落後主服務器,可以使用半同步複製

主節點:

安裝插件,文件在/usr/local/mysql/lib/plugin

MariaDB> install plugin rpl_semi_sync_master soname'semisync_master.so'

show global variables like '%semi%'可以查看安裝後semisync的狀態

編輯配置文件:

rpl_semi_sync_master_enabled =on 開啓半同步

rpl_semi_sync_master_timeout=2000 超時時間設爲2000毫秒

從節點:

安裝插件

MariaDB> install plugin rpl_semi_sync_slave soname'semisync_slave.so'

show global variables like '%semi%'可以查看安裝後semisync的狀態

編輯配置文件:

rpl_semi_sync_slave_enabled =on 開啓半同步

重啓slave線程

stop slave io_thread;

start slave io_thread;

使用show global status like '%semi%' 查看狀態是否啓動

4.複製過濾器,不復制所有數據庫,只複製指定的數據庫

(1)主服務器僅向二進制日誌中記錄有特定數據庫相關的寫操作

問題:即時點還原將無法實現

binlog_do_db =                            數據庫白名單

binlog_ignore_db =                      數據庫黑名單

(2)從服務器的SQL_THREAD僅在中繼日誌中讀取特定數據相關的語句並應用在本地

問題:會造成網絡帶寬和磁盤IO的浪費

 Replicate_Do_DB:                       數據庫白名單

 Replicate_Ignore_DB:                 數據庫黑名單

 Replicate_Do_Table:

 Replicate_Ignore_Table:

 Replicate_Wild_Do_Table:            用通配符匹配

 Replicate_Wild_Ignore_Table:

 

例:

stop slave;

set global Replicate_Do_DB=tpweb;

start slave;

5.基於SSL的複製

前提:支持SSL

show global variables like '%ssl%';查看ssl狀態,在編譯時指定開啓ssl

MariaDB[(none)]> show global variables like '%ssl%';

+---------------+----------+

|Variable_name | Value    |

+---------------+----------+

| have_openssl  |ENABLED |

| have_ssl      | ENABLED |

| ssl_ca        |     ca證書路徑    |

| ssl_capath    |   一堆ca證書路徑     |

| ssl_cert      |   ca給自己發的證書      |

| ssl_cipher   |     加密算法     |

| ssl_key      |     私鑰     |

+---------------+----------+

(1) 主服務器配置證書和私鑰,並創建一個要求必須使用SSL連接的複製賬號(使用REQUIRE SSL)

(2)SLAVE端連接MASTER時,使用MASTER_SSL相關的選項來配置證書等信息

6.跟複製有關的文件

在從節點上的master.info用來保存主從連接時的相關信息,如賬號,密碼

relay-log.info:保存了當前slave節點上已經複製的當前二進制日誌和本地中繼日誌的對應關係,即position位置

7.複製的監控和維護

(1)清理日誌:使用PURGE

(2)監控複製:

show master status

show binlog events

show binary logs

 

show slave status

(3)如何判斷slave是否落後於master

show slave status中的Seconds_Behind_Master: NULL來觀察

(4)如何確定主從節點數據是否一致

①在創建表時啓用checksum,之後可以通過show table status查看主從節點同一張表的checksum是否一致

②使用percona-tools中的pt-table-checksum

(5)數據不一致時的修復方法:

重新複製master節點的數據,重新同步

配置MySQL主從

例:172.16.37.20做主節點,172.16.37.21做從節點

master

1.啓用二進制日誌

wKiom1WI9f_R23_4AAASv-8C_b8296.jpg

2.設置一個在當前集羣中唯一的server-id

wKioL1WI98jSq16eAAARnNz-1Bw094.jpg

3.創建一個有複製權限[REPLICATIONSLAVE,REPLICATION CLIENT]的賬號

mysql命令行中執行

MariaDB [(none)]> grant replicationclient,replication slave on *.* to 'testuser'@'172.16.%.%' identified by'123456';

wKiom1WI9lSRrl0KAACPWpSXHAs392.jpg

slave

1.啓動中繼日誌,註釋二進制日誌

wKioL1WI-BWgnEz0AAAqGnPPzn4041.jpg

2.設置一個在當前集羣中唯一的server-id

wKiom1WI9mXjctQIAAAQVC4Am38236.jpg

3.不允許client寫入操作

wKiom1WI9m6THPKiAAARzKfV4Qs064.jpg

4.利用有複製權限的用戶賬號連接至主服務器,並啓動複製線程

MariaDB [(none)]>  change master tomaster_host='172.16.37.20',master_user='testuser',master_password='123456',master_log_file='master-bin.000001',master_log_pos=419,master_connect_retry=5,master_heartbeat_period=2;

master_connect_retry=5:表示每5s重連一次

master_heartbeat_period=2:表示每2s探測一次master的健康狀態

 

master中查出master_log_pos的值;

wKioL1WI-C7xUolnAADJQ3_rWEU886.jpg

 

 

5.show slavestatus查看slave狀態,並用startslave;啓動線程

MariaDB[(none)]> show slave status\G

***************************1. row ***************************

               Slave_IO_State:

                  Master_Host: 172.16.37.21

                  Master_User: testuser

                  Master_Port: 3306

                Connect_Retry: 5

              Master_Log_File:master-bin.000001

          Read_Master_Log_Pos: 419

               Relay_Log_File:mysql-relay.000001

                Relay_Log_Pos: 4

        Relay_Master_Log_File:master-bin.000001

             Slave_IO_Running: No

            Slave_SQL_Running: No

              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: 419

              Relay_Log_Space: 245

              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: NULL

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: 0

測試:在master創建數據庫,在slave上查看是否複製成功

 

 

 

雙主模型:

互爲主從:

1.數據可能不一致;

2.idauto_increment定義一個節點使用基數id,另一節點使用偶數id,但會產生id不連貫

show global variables like '%increment%';查看偏移量

wKiom1WI9pDh7jW9AADqonsKLp8375.jpg

auto_increment_offset 表示從幾開始

auto_increment_increment表示一次增加幾

定義一個節點使用基數id

set @@auto_increment_offset=1;

set @@auto_increment_increment=2;

定義一個節點使用偶數id

set @@auto_increment_offset=2;

set @@auto_increment_increment=2;

 

 

配置:

1.各自使用不同的server-id

172.16.37.20

wKiom1WI9sqgd_zHAAAOM8MNh9g076.jpg

172.16.37.21

wKiom1WI9tfw10UaAAASnfsnM54406.jpg

2.都啓用二進制日誌和中繼日誌

172.16.37.20

wKioL1WI-JuBeL2HAAArWw1m1vc403.jpg

172.16.37.21

wKiom1WI9u_QrqQtAAAqexXepBU416.jpg

3.解決自增字段問題

172.16.37.20

wKiom1WI9vngNuhpAAA6mbehSJ0813.jpg

172.16.37.21

wKioL1WI-LmSuV_uAAArY2hr77c926.jpg

4.都授權有複製權限的賬號

172.16.37.20/21都執行授權

MariaDB [(none)]> grant replicationclient,replication slave on *.* to 'testuser'@'172.16.%.%' identified by'123456';

5.各自把對方指定爲主服務器

172.16.37.20

showmaster status;查看

wKiom1WI9x7xzc_NAAC6yAm6O1A846.jpg

再指定master爲對方

MariaDB [(none)]> change master to master_host='172.16.37.21',master_user='testuser',master_password='123456',master_log_file='mysq2l-bin.000001',master_log_pos=424,master_connect_retry=5,master_heartbeat_period=2;

show slave status\G 查看slave狀態,並用startslave;啓動線程

172.16.37.21

showmaster status;查看

wKioL1WI-M3xq5alAADICwK-zow263.jpg

再指定master爲對方

MariaDB [(none)]> change master to master_host='172.16.37.20',master_user='testuser',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=424,master_connect_retry=5,master_heartbeat_period=2;

show slave status\G 查看slave狀態,並用startslave;啓動線程

 

測試:在兩個節點上創建數據庫,並在對方的Client上查看

 

 

讀寫分離:

爲了實現讀寫分離,寫操作都發往master,讀都發往slave

 

讀寫分離器:

mysql-proxy 測試版-->奇虎360的二次開發版 (atlas)

amoeba 淘寶研發的

dbrelay 商業產品

 

mysql-proxy:

先配置主從服務器

master : 172.16.37.20

1.啓用二進制日誌

wKioL1WI-RuSDXQ7AAASv-8C_b8371.jpg

2.設置一個在當前集羣中唯一的server-id

wKiom1WI92niMqsmAAARnNz-1Bw761.jpg

3.創建一個有複製權限[REPLICATIONSLAVE,REPLICATION CLIENT]的賬號

mysql命令行中執行

MariaDB [(none)]> grant replicationclient,replication slave on *.* to 'testuser'@'172.16.%.%' identified by'123456';

wKioL1WI-SqiwNTfAACPWpSXHAs674.jpg

 

slave : 172.16.37.21

1.啓動中繼日誌,註釋二進制日誌

wKiom1WI93nRNRDQAAAqGnPPzn4926.jpg

2.設置一個在當前集羣中唯一的server-id

wKioL1WI-TrTRAs0AAAQVC4Am38607.jpg

3.不允許client寫入操作

wKiom1WI94niceBkAAARzKfV4Qs832.jpg

4.利用有複製權限的用戶賬號連接至主服務器,並啓動複製線程

MariaDB [(none)]>  change master tomaster_host='172.16.37.20',master_user='testuser',master_password='123456',master_log_file='master-bin.000001',master_log_pos=419,master_connect_retry=5,master_heartbeat_period=2;

master_connect_retry=5:表示每5s重連一次

master_heartbeat_period=2:表示每2s探測一次master的健康狀態

 

master中查出master_log_pos的值;

wKioL1WI-UjhDnJfAADJQ3_rWEU035.jpg

5.show slavestatus查看slave狀態,並用startslave;啓動線程

 

再設置登錄用戶grant all on *.* to 'lx'@'%' identified by'123456';

 

配置mysql-proxy代理服務器,172.16.37.9

epel源:yum -yinstall mysql-proxy

使用官方二進制格式文件中的rw-splitting.lua腳本進行讀寫分離

 

配置文件:/etc/mysql-proxy.cnf

[mysql-proxy]

daemon= true

pid-file= /var/run/mysql-proxy.pid

log-file = /var/log/mysql-proxy.log  # 可以選擇關閉日誌,因爲記錄的非常詳細,佔用磁盤空間

log-level = debug 

max-open-files= 1024

plugins= admin,proxy

user= mysql-proxy

#

#ProxyConfiguration

proxy-address = 0.0.0.0:3306                                          #代理服務監聽的地址和端口

proxy-backend-addresses =172.16.100.7:3306            #支持讀寫操作的後端mysql                      

proxy-read-only-backend-addresses =172.16.100.8:3306        # 只讀後端

#proxy-lua-script=

proxy-lua-script =/usr/lib64/mysql-proxy/lua/rw-splitting.lua #讀寫分離腳本,可以註釋使用默認

#proxy-skip-profiling= true

#

#Admin Configuration

admin-address = 0.0.0.0:4041  # 默認管理程序監聽端口

admin-lua-script= /usr/lib64/mysql-proxy/lua/admin.lua

admin-username = admin # 管理用戶

admin-password = admin # 管理密碼

 

啓動服務:/etc/init.d/mysql-proxy start

 

測試:mysql -h172.16.37.9 -ulx -p123456 -e 'create database proxy-test';然後去主從服務器上查看是否創建了此database

 

複製的問題和解決方案:

(1) 數據損壞或丟失

從服務器崩潰回去找:master.info

最好在從節點上啓動                        

snyc_master_info=1

snyc_binlog=1

但會增加IO壓力

 

(2) 建議不要混合使用存儲引擎,可以考慮都使用InnoDB

 

(3) 注意要使用唯一的serverid

 

(4) 複製延遲

重啓從服務器的slave線程,要確保當前從服務器沒有正在進行的請求和長連接

 

數據庫切分:sharding

垂直切分:按表進行切分

水平切分:按表中的行進行的切分

 

切分條件:讀集中,寫離散

 

MySQL數據庫的向外擴展方式:複製、拆分、sharding

 

拆分方式:

按功能拆分:也即按應用拆分;

數據分片:

選擇切分鍵

把數據存儲在哪裏?

從哪兒讀數據?

 

數據庫切分框架:

cobar

gizzard

HibernatShards

HiveDB

 

 


 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章