MySQL binlog相關分析

一、redolog、binlog的簡單分析mysql

  圖解:redolog和binlog機制sql

二、開啓binlog及關注點shell

三、關注binlog的相關參數數據庫

四、binlog模式分析vim

五、關於binlog的使用緩存

補充:雙一模式安全

1、區別redolog和binlog服務器

一、以下表格的一個簡單對比session

  redolog binlog
日誌做用 保護髒數據 數據庫備份恢復使用
引擎支持 只適合InnoDB引擎 全部引擎
日誌格式 物理日誌 邏輯日誌,SQL語句
提交方式 快速提交 提交時一次性寫入
保存形式 會被循環覆蓋 長期保存

二、redolog記錄的是對於每一個頁的修改oracle

  數據頁地址、行地址、操做類型(I/D)、數據

  e.g:一個update修改100行,至少產生200行redo日誌,因此DML產生的redo可能很大:

    100、二、D

    100、二、I、'value'

    ……

  實際就是update table set ……100(數據頁地址) 2(行地址)

三、binlog只是記錄DML、DDL、DCL,不記錄SELECT

  經過參數設置控制binlog的記錄模式:

  一、語句模式

    e.g:delete from t1 where id<=1000;

  二、行模式

    delete from t1 where id=1;

    delete from t1 where id=2;

    ……

    delete from t1 where id=1000;

四、圖解redolog、binlog機制

注意:

  在oracle裏面雖然redolog也是循環覆蓋的,可是在循環覆蓋以前,數據庫會將redo拷貝出來作個歸檔,因此oracle裏能夠用redolog作數據恢復。 

 

2、開啓binlog及相關關注點

一、開啓binlog

mysql> show variables like 'log_bin'; +---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | OFF   |  #默認是關閉的
+---------------+-------+
 mysql> set @@global.log_bin=on; ERROR 1238 (HY000): Variable 'log_bin' is a read only variable

  修改配置文件/etc/my.cnf,[mysqld]下添加:

server-id=1 log-bin=mysql-bin

  重啓MySQL,便可……binlog的啓動大概會爲mysql增長1%的負載,所以在絕大多數狀況下,binlog都不會成爲mysql的性能瓶頸,因此通常都是會開啓binlog的。

二、binlog的存放

mysql> show variables like 'log_bin%'; +---------------------------------+-------------------------+
| Variable_name                   | Value                   |
+---------------------------------+-------------------------+
| log_bin                         | ON                      |
| log_bin_basename                | /mydata/mysql-bin       |  #binlog文件,注意:每次重啓會生成一個新的binlog文件
| log_bin_index                   | /mydata/mysql-bin.index |  #二進制的索引文件,記錄使用的binlog文件名

三、如何手工切換binlog

  一、重啓數據庫,每次重啓都會新切binlog

  二、mysql> flush logs;

四、查看binlog日誌文件

[root@localhost mydata]# mysqlbinlog -vv mysql-bin.000001 
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; # at 4 #170707  8:14:29 server id 1  end_log_pos 123 CRC32 0xf307168d     Start: binlog v 4, server v 5.7.14-log created 170707  8:14:29 at startup # Warning: this binlog is either in use or was not closed properly. ROLLBACK/*!*/; BINLOG '
…………

 

3、關注binlog相關參數

  mysql> show variables like '%bin%';

一、binlog_cache_size  

  //設置binlog cache(默認32K),每一個線程單獨分配內存空間

  全部未提交的二進制日誌文件會被記錄到用戶工做空間的binlog cache中,等該事務提交時直接將緩衝區中的binlog寫入二進制日誌文件裏

mysql> show global status like 'Binlog_cache_disk_use'; +-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Binlog_cache_disk_use | 0     |
+-----------------------+-------+

  判斷binlog_cache_size是否設置太小的依據,若是Binlog_cache_disk_use>0(次數),說明事務未提交,binlog在用戶工做空間存放不下,須要借用tmp目錄。

二、log_bin

  //設置名字前綴

  --log-bin [=file_name]:設置此參數表示啓用binlog功能,並指定路徑名稱,生產中都要開啓binlog。

  sql_log_bin:會話級別的binlog開關控制,默認是開啓的,能夠在當前會話級別動態修改臨時關閉binlog(主從延遲優化),set session sql_log_bin=0;

三、sync_binlog

  //同步binlog的方式

  0:默認,提交同步到文件系統緩存

  1:commit,經過fsync方式,直接寫入disk的binlog文件中(最安全),與redo的雙一模式。

  >1:sync_binlog=N,若是N>1,在乎外發生的時候,就表示會有N-1個dml沒有被寫入binlog中,有可能就會發生主從數據不一致的狀況。

四、max_binlog_size

  //binlog文件大小,默認1G

  若是是row模式,須要增長binlog文件的大小,由於行模式產生的日誌量相對較大。若是超過了該值,就會產生新的日誌文件,後綴名+1,而且記錄到.index文件裏面。

五、binlog_format

  //row、statement、mixed,設置binlog記錄的模式:行模式、語句模式、mixed模式。動態參數,能夠會話級別修改

六、--binlog-do-db、--binlog-ingore-db

  //command-line format,表示須要寫入或者忽略寫入哪些庫的日誌,默認爲空,表示能夠將全部庫的日誌寫入到二進制文件裏面。

七、log-slave-updates

  //啓用從機服務器上的slave日誌功能,使這臺計算機能夠用來構成一個鏡像鏈(A->B->C)  ,可讓從庫上面產生二進制日誌文件,在從庫上再掛載一個從庫。

八、binlog_rows_query_log_events

  //便於定位執行過的SQL語句

九、expire_logs_days

  //binlog過時清理時間,默認是0:不自動清除

  binlog的刪除策略,假設expire_logs_days=5,表示系統保留5天binlog,第六天到來時會刪除第一天的binlog。

  一、刪除策略的風險:

    一、刪除會致使太高的io,從而致使業務出現性能抖動

    二、主從延遲

  二、解決:手工主動刪除binlog

    PURGE BINARY LOGS  #同時刪除binlog文件和binlog索引文件記錄,如此說來用rm刪除binlog和vim修改對應binlog索引文件記錄,效果同purge。

Syntax:   PURGE { BINARY | MASTER } LOGS   { TO 'log_name' | BEFORE datetime_expr } mysql> PURGE BINARY LOGS TO 'mysql-bin.000003';  #刪到3,也就是刪了一、2

 

4、binlog_format有哪些

一、STATEMENT

  每一條會修改數據的sql都會記錄在binlog中。

  優勢:不須要記錄每一行的變化,減小了binlog日誌量,節約了IO,提升性能。只須要記錄在 master 上所執行的語句的細節,以及執行語句時候的上下文的信息。

  缺點:因爲記錄的只是執行語句,爲了這些語句能在slave上正確運行,所以還必須記錄每條語句在執行的時候的一些相關信息,以保證全部語句能在slave獲得和在master端執行時候相同的結果。像一些特定函數功能,slave可與master上要保持一致會有不少相關問題(如sleep()函數,rand()函數等會出現問題warning)。

二、ROW

  不記錄sql語句上下文相關信息,僅保存哪條記錄被修改,也就是說日誌中會記錄成每一行數據被修改的形式,而後在 slave 端再對相同的數據進行修改。

  優勢:binlog中能夠不記錄執行的sql語句的上下文相關的信息,僅須要記錄那一條記錄被修改爲什麼了。因此rowlevel的日誌內容會很是清楚的記錄下每一行數據修改的細節。並且不會出現某些特定狀況下的存儲過程,或function,以及trigger的調用和觸發沒法被正確複製的問題。

  缺點:在 row 模式下,全部的執行的語句當記錄到日誌中的時候,都將以每行記錄的修改來記錄,這樣可能會產生大量的日誌內容。

三、MIXED

  是以上兩種level的混合使用,通常的語句修改使用statment格式保存binlog,如一些函數,statement沒法完成主從複製的操做,則採用row格式保存binlog,MySQL會根據執行的每一條具體的sql語句來區分對待記錄的日誌形式,也就是在Statement和Row之間選擇一種;

  新版本的MySQL中對row模式也被作了優化,並非全部的修改都會以rowl來記錄,像遇到表結構變動的時候就會以statement模式來記錄。至於update或者delete等修改數據的語句,仍是會記錄全部行的變動。

 

5、binlog的使用

一、二進制日誌兩個最重要的使用場景

  一、MySQL replication在master端開啓binlog,master把它的二進制日誌傳遞給slaves來達到master-slave數據一致的目的,也就是主從備份。

  二、數據恢復,經過使用mysqlbinlog工具來使恢復數據

二、經常使用binlog日誌操做命令

  一、查看全部binlog日誌列表

    mysql> show master logs;

  二、查看master狀態,即最後(最新)一個binlog日誌的編號名稱,及其最後一個操做事件pos結束點(Position)值

    mysql> show master status;  //結合上述binlog文件,進行binlog生成速度監控

  三、刷新log日誌,自此刻開始產生一個新編號的binlog日誌文件

    mysql> flush logs;  //注:每當mysqld服務重啓時,會自動執行此命令,刷新binlog日誌;在mysqldump備份數據時加 -F 選項也會刷新binlog日誌;

  四、重置(清空)全部binlog日誌

    mysql> reset master;

三、查看binlog日誌內容

  一、OS層面查看binlog文件

    shell> mysqlbinlog -vv mysql-bin.000001

  二、數據庫層面show binlog events

    mysql> show binlog events [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count];

    選項解析:

      一、in 'log_name':指定要查詢的binlog文件名(不指定就是第一個binlog文件)

      二、from pos:指定從哪一個pos起始點開始查起(不指定就是從整個文件首個pos點開始算)

      三、limit [offset,]:偏移量(不指定就是0)

      四、row_count:查詢總條數(不指定就是全部行)

mysql> show binlog events FROM 9451 limit 1\G; *************************** 1. row *************************** Log_name: mysql-bin.000001 Pos: 9451 Event_type: Query Server_id: 1 End_log_pos: 9561 Info: use `db1`; create index i_n_a on t1(name,address) 1 row in set (0.00 sec)

四、從binlog日誌恢復語法

  一、恢復語法格式:

    # mysqlbinlog [選項] mysql-bin.0000xx | mysql -u用戶名 -p密碼 數據庫名

  二、經常使用選項:

    --start-position=953 起始pos點

    --stop-position=1437 結束pos點

    --start-datetime="2017-6-8 13:18:54" 起始時間點

    --stop-datetime="2017-6-8 13:21:53" 結束時間點

    --database=TEST 指定只恢復TEST數據庫(一臺主機上每每有多個數據庫,只限本地log日誌)

  三、不經常使用選項:

    -u --user=name #Connect to the remote server as username.鏈接到遠程主機的用戶名

    -p --password[=name] #Password to connect to remote server.鏈接到遠程主機的密碼

    -h --host=name #Get the binlog from server.從遠程主機上獲取binlog日誌

    --read-from-remote-server #Read binary logs from a MySQL server.從某個MySQL服務器上讀取binlog日誌

使用小結:

  實際是將讀出的binlog日誌內容,經過管道符傳遞給mysql命令。這些命令、文件儘可能寫成絕對路徑;所謂恢復,就是讓MySQL將保存在binlog日誌中指定段落區間的SQL語句逐個從新執行一次而已。

 

關於雙一模式:

  一、redolog、binlog:雙1(絕對安全)

    一、innodb_flush_log_at_trx_commit=1

    二、sync_binlog=1

  二、innodb_support_xa=1:分佈式事務,默認開啓ON

    一、保證binlog裏面存在的事務必定在redo log裏面存在

    二、保證binlog裏面事務順序與redo log事務順序一致性

    三、commit,要麼成功要麼失敗,防止出現主從不一致

  因此在雙一的狀況下,也要配合開啓innodb_support_xa,更安全。

相關文章
相關標籤/搜索