這次我們要探索更精細的binlog內容,上次討論的Query_event和Rows_event肯定有讓你疑惑不解的問題。Query_event中的status-vars環境變量有哪些,Rows_event的數據類型是什麼,元數據又是個什麼鬼東西,今天我們就來一一解答。
一、Query_event中的令人費解的status-vars
status-vars據說是為了兼容低版本的mysql服務器而加入的環境變量設置,告訴低版本的mysql服務器sql語句是在什麼環境下執行的
具體的格式是狀態枚舉值+狀態參數
下面以狀態枚舉值分別講下比較重要的幾個狀態:
(1)0x00 Q_FLAGS2_CODE 4個字節
這個主要是對於SQL_AUTO_IS_NULL、FOREIGN_KEY_CHECKS、UNIQUE_CHECKS、AUTOCOMMIT的設置,SQL_AUTO_IS_NULL是自動填充NULL,FOREIGN_KEY_CHECKS是外鍵檢查,UNIQUE_CHECKS是唯一鍵索引檢查,AUTOCOMMIT就是自動提交,在此處SQL_AUTO_IS_NULL = 1,其他均為0。
(2)0x01 Q_SQL_MODE_CODE 8個字節
這裡的配置要參考SET sql_mode
: http://dev.mysql.com/doc/refman/5.7/en/set-variable.html,這裡有大量的sql環境變量
對應的狀態列表可以參考http://dev.mysql.com/doc/internals/en/query-event.html#q-sql-mode-code
可以參考下面的中文翻譯:
1)單項模式:
2)混合模式:
1. ANSI:該項如果設置,和REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE等價,在
2. DB2:該項如果設置,與PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS一起設置等價。
3. MAXDB:該項如果設置,與PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER一起設置等價。
4. MSSQL:該項如果設置, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS. 一起設置等價。
5. TRADITIONA:該項如果設置,與STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION
6. POSTGRESQL:該項如果設置,與PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS一起設置等價。
7. ORACLE:該項如果設置,與PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS一起設置等價。
8. MYSQL323:僅對SHOW CREATE TABLE有影響。
9. MYSQL40:同上。
(3)0x02 Q_CATALOG
默認記錄為"\x3std\x0",即mysql服務器所使用的目錄。一字節長度+NULL字符串
(4)0x03 Q_AUTO_INCREMENT
與AUTO_INCREMENT有關,4字節,前2個字節表示AUTO_INCREMENT,後2個字節表示AUTO_INCREMENT_OFFSET
(5)0x04 Q_CHARSET_CODE
字符集 在連接時客戶端設定的字符集(2字節)+連接校對時的字符集(2字節)+服務器校對時的字符集(2字節)
(6)0x05 Q_TIME_ZONE_CODE
時區 一字節長度+字符串,如"\x6+08:00" 就是北京時間,這個待確認。
(7)0x07 Q_LC_TIME_NAMES_CODE
星期和月的名稱,例如:在英文文中星期一是MON,一月是Jan,在其他文字中就不是這樣。
二、Rows_event的數據類型和元數據
這裡僅僅介紹常用的數據類型
(1)日期時間類型
1)元數據代表的可以精確到微秒的值 n通常為0-3
對與這種類型的在my_time.h中有相應的定義。
MYSQL_TYPE_DATETIME2,是用longlong數據存儲的, 固定是4位+n,元數據代表的是額外數據的長度n
1 //來自mysql5.7.13源碼 my_time.c 2 //將longlong時間轉化成字符串 3 //longlong時間格式: 4 //按位計算 5 //1 bit sign(used when on disk) 6 //17 bits year * 13 + month(year 0 - 9999, month 0 - 12) 7 //5 bits day(0 - 31) 8 //5 bits hour(0 - 23) 9 //6 bits minute(0 - 59) 10 //6 bits second(0 - 59) 11 //24 bits microseconds(0 - 999999) 12 // 13 //Total: 64 bits = 8 bytes 14 // 15 //SYYYYYYY.YYYYYYYY.YYdddddh.hhhhmmmm.mmssssss.ffffffff.ffffffff.ffffffffView Code
MYSQL_TYPE_TIME2,也是是用longlong數據存儲的, 固定是3位+n,元數據代表的是額外數據的長度n
MYSQL_TYPE_TIMESTAMP2,是時間戳,固定是4位,元數據代表的是額外數據的長度n
MYSQL_TYPE_NEWDATE也是以這種方式存的,但是沒有元數據
2)不存在元數據,以十進制yyyymmddhhmmss存儲的
MYSQL_TYPE_TIMESTAMP,MYSQL_TYPE_DATETIME都是以這種方式存的。
MYSQL_TYPE_TIME是時間戳。
3)MYSQL_TYPE_YEAR,不存在元數據。
這個是1900開始的年份存的
(2)整形,不存在元數據
MYSQL_TYPE_TINY, MYSQL_TYPE_SHORT, MYSQL_TYPE_INT24,MYSQL_TYPE_LONG,MYSQL_TYPE_LONGLONG和原先我們理解的方式一樣,只不過是小端數據
(3)實數型
MYSQL_TYPE_FLOAT和MYSQL_TYPE_DOUBLE也是通過小端數據存儲的,不同的是他們有一字節元數據,他們的元數據代表他們有效數據的長度。
MYSQL_TYPE_NEWDECIMAL這個小數存儲方式不是很明確,僅僅在decimal.h中有定義,但是他的元數據第一個字節代表他有效數據的長度,第二個代表他的精度即小數點後長度
(4)字符串類型
MYSQL_TYPE_VARCHAR 他兩字節的元數據是他的最長長度。
MYSQL_TYPE_STRING,MYSQL_TYPE_VAR_STRING 他們的元數據第一個字節代表真正的類型,而第二個字節代表存儲字符串長度的字節數大小
(5)bit類型
MYSQL_TYPE_BLOB 他的元數據存儲的是bit類型長度的字節數大小
MYSQL_TYPE_BIT 他的元數據存儲第一個字節代表有多少bit,而第二個字節代表存儲bit類型的字節數大小
為此我們可以得到結論,元數據更多存儲的是該類型的長度信息。
具體更詳細的請查看mysql5.7.13的源碼 log_event.cc:1953::log_event_print_value()獲取更多的信息