MySQL數據庫再回首

前言:

數據庫是程序員的數據源泉,加上近期 要開發DB可視化、性能分析的功能 從新回顧一下MySQL知識,如下是筆記;html

 

 

MySQL架構

 

 

 

 

MySQL基礎理論

 

1.什麼是關係型數據庫?node

關係型數據庫,這個關係怎麼講呢?簡單來講關係就是 經過行、列組成一張二維表 把全部數據關聯、表現出來;python

列:從不一樣方面描述1類實體數據的屬性;mysql

行:1行=1條實體數據;linux

 

2.爲何要使用數據庫管理系統(DBMS)?c++

 

若是咱們的數據只是像/etc/password/這樣大小的一個文件,咱們使用文本文件存儲數據是徹底沒有問題的;
可是使用文件的方式存儲數據有下列缺陷:程序員

數據冗餘web

沒法簡單描述數據之間的關聯性(外鍵、多對多、1對1)在文件中實現起來困難redis

文本文件沒法保存數值數據(浮點、整型)丟失精度、沒法計算算法

最重要的是 當文件中數據每人劇增變得異常龐大的時候,咱們從中查找符合條件的內容將會變得異常困難;

好比:/etc/password這個文件變成100G的時候,咱們從中查找出 …^r的用戶,怎麼查找?。

也許你會想到使用grep/egrep命令去查找,是的我能找到沒有任何問題;

可是在100G的文件中尋找符合條件的行會遇到如下問題:

grep/egrep也是程序 若是想要 查詢 就須要把100G的文件載入內容,須要多大的內存?,即使有這麼大的內存會產生多大IO?花銷多大時間?

 

於以上內容使用一個簡單的文件來存儲數據,只能 在早期 知足1個簡單數據模型的應用程序;

 

 

3.什麼是搜素引擎?

若是1個python程序使用文件來保存數據,數據都存儲在硬盤上,python和數據打交道的接口是什麼?文件系統的系統調用接口;

文件存儲在硬盤上,咱們經過系統調用調用到的數據都是數據流(只不過經過文件系統抽象以後才表現爲文件)若是和文件數據流打交道這就意味着你的python程序就須要維護文件句柄、內容指針(讀到第幾行了?)、什麼時候關閉文件、關閉以前清理緩衝區....管理;

 

咱們都知道文件系統把數據放在磁盤的某1個塊上的,假如說這個python程序想要訪問某1數據塊,python也須要將這個文件的全部內容載入到內存中才能訪問的;

爲何是全部文件內容?因程序自己沒法界定符合條件的內容到底存儲在 哪一個數據塊上?

因而在文件系統之上又封裝了一層管理功能,這個管理工具向下能夠和文件系統打交道,將N個文件系統的塊 組織成1個更高級別的邏輯存儲塊。

劃分出這些邏輯塊以後,就能夠知道那些數據存儲在哪一個數據塊上並記錄下來;因此好比當咱們查詢/etc/password的1-5行時就能夠載入部分數據塊了;由於如今已經知道了那些數據在哪一個數據塊上,無需在訪問部分數據時加載所有文件的數據塊了;

 

可是還有1個問題 若是 咱們要查詢 /etc/password 以^r開頭的用戶

那麼就會出現1個問題即便你知道 某1行數據在哪1數據塊?但也須要載入所有數據塊(若是1個數據塊對應1行數據)去每一個塊上找1下;

因此咱們能夠把一些搜素條件單獨組合成搜素碼,單獨存儲在1個數據塊上,這樣用戶搜素的時候就能夠只載入1個數據塊而不是所有了!

若是 咱們要查詢 /etc/password 以^r開頭的用戶全部信息包含家目錄、登陸shell

因此咱們不只要把搜素碼單獨存儲起來,還有存儲它相關信息所在搜素塊的映射關係;這就是索引

 

 

索引分級:

若是把全部搜素條件都作成搜素塊(索引)那麼數據庫每次啓動加載全部全部索引信息也是很是慢慢的,索引也須要分級;

 

數據庫緩衝區:

加載索引 、常常訪問的數據到內存加速用戶訪問速度;

 

搜素引擎:

以上內容 將數據從1個物理模型轉換成數據庫能理解的數據庫模型、根據上層程序調用不加載所有數據塊而非所有數據的 就是數據庫引擎;

讀鎖:共享鎖

寫鎖:獨佔鎖

 

 

httpMPM

multi-processing  module  併發響應模型

http支持三種方式解決併發問題:

prefork:1個進程處理1個請求

worker:多個進程處理1個請求

event:1個線程處理多個請求(IO多路複用 + 協程)時間通知回調 協程切換

 

mysq併發:1個線程響應1個用戶請求;

爲啥不用1個線程處理多個數據庫用戶呢?1的用戶的請求處理邏輯複雜開發難度比較大;

 

4.爲何要用mysql線程池?

由於mysql的線程比較重量級,在大併發的場景下線程的建立、釋放、銷燬都須要必定時間,因此爲了最大限度複用線程就有了進程池,用戶使用完線程以後清除該用戶的數據但不銷燬而是把該線程回收到線程池中,留個下1個用戶繼續使用;

還有1點就是能夠限制併發的數量;

 

5.sql語句分類

DML:對數據庫數據數據的操做Insert、Update、Delete、Select

DDL:對數據庫對象(表、視圖、索引、存儲過程、存儲函數)建立、刪除、修改操做;Create Drop Al

Alter

DCL:Grant、Revoke 用戶受權和回收權限

 

6.事物是什麼?

一組DML就是一個事物,它具備如下特性:

原子性:一組DML(多條增、刪、改、查的sql語句)要麼都執行,要麼都不執行;(當作1個總體來管理)

一致性:事物操做數據總量保存不變A向B轉帳100, A的帳戶少了100,B的帳戶就要加100,就這麼簡單;

隔離性:隔離多個事物,避免多個事物同時進行;

隔離級別

讀未提交

讀提交

可重讀

可串行化

持久性:事物的數據一旦提交以後不能丟失,中間出現問題能夠回滾;經過事物日誌來保證;

 

 

7.Mysql的日誌類型

錯誤日誌

查詢日誌

慢查詢日誌

事物日誌

二進制日誌

中間日誌

 

 

8.DBA職責

設計表結構、安全性和受權、保障數據庫可用性、故障恢復、數據庫調優

 

 

 

2、關係型數據庫索引、數據庫文件的組織方式

1.mysql的數據類型 CHAR(定長)和VARVHAR(變長)

CHAR數據類型的長度是固定的,VARCHAR數據類型的長度是可變、非固定的,

變長:VARCHAR(20)  存儲root字符串佔用數據庫5字節空間, 優點:節省空間、其長度可變佔用空間可擴展;應用在數據最大和最小長度相差太大的場景;

定長:CHAR(20)        存儲root字符串佔用數據庫20字節空間,優點:方便搜素引擎存儲、索引查找,數據最大和最小長度相差不太大的場景都要儘可能使用CHAR類型;

 

2.數據庫文件

數據文件:堆文件(組織無序)、有序文件(組織有序)、散列組織(hash函數+hash桶)

索引文件:有序索引文件、無序索引文件

日誌文件:存儲搜素引擎的操做記錄,便於追溯、恢復數據;

 

3.數據庫索引

聚簇索引

搜索引擎 把數據 存儲在索引上所指向數據庫塊位置,若是索引自己有序,數據記錄也是有序的,這種索引就是聚簇索引,按這種方式組織的數據庫文件也叫有序數據、聚簇文件;(有序文件+有序索引文件+存儲在一塊兒)

 

非聚簇索引

與相反若是索引自己無序 因而數據記錄就是無序的,或者索引有序、數據記錄無序 這種索引就是非聚簇索引,按這種方式組織的數據庫文件也叫無序數據、堆文件;

 

非聚簇索引包含散列(hash)索引

若是散列文件組織就使用hash算法去存儲和查找;注意hash算法的時間複雜度=o(1),但不適合範圍查找;由於即便數據會被hash算法隨機分配到不一樣的hash桶裏;

 

小結

索引和數據庫文件結構關聯性很大

 一般樹狀結構索引都是有序的稱爲聚簇索引,輔助索引、hansh索引無序稱爲非聚簇索引。

 

4. 兩大引擎存儲數據庫、索引文件的特徵

每張表都有3個文件;

MyISM: 數據文件=表名.MYD,索引文件=表名.MYI ,表定義文件=表名.frm

InnoDB:

每張表的全部數據都放在表空間中(ibdata),表空間能夠被多個位於不一樣數據庫的表共享;

定義文件在數據庫目錄中;

 

5.MySQL數據字典

保存數據庫的元數據

關係的名字

張表中各列的名字

每列的數據類型和長度

每張表上的視圖名稱

 

受權用戶的名字

用戶受權和帳戶信息

以上信息存儲在mysql庫;

 

統計類數據

每一個庫中屬性的個數

每一個表中行的個數

每一個關係的存儲組織方法

infomation_schema存儲統計類信息;

 

Mysql安裝自帶如下3個庫就是用來存儲數據字典信息的;

mysql庫:帳號受權

information_schema庫:統計類信息

performance_schema 庫:存儲性能相關信息

總結:^_^ 有了以上自帶的3個庫彷彿看到了DB可視化功能的大門~~~~

import pymysql
db = pymysql.connect("172.17.10.112", "webproject", "xxxxxx1234","web")
cursor = db.cursor()
cursor.execute(" show variables like 'max_connections';") #查當前登陸用戶聲明的變量
cursor.execute(" show global variables")                    #查當前全局聲明的變量
cursor.execute("show status like '%Threads_connected%'") #查看MySQL運行狀態 https://www.cnblogs.com/zuxing/articles/7761262.html
print(cursor.fetchall())
# 關閉數據庫鏈接
db.close()
在線查看部分信息

 

3、安裝MySQL 

主要描述基於centos7 64位系統源碼安裝MySQL5.6.19

爲啥不使用 yum安裝呢?由於下載MySQL源碼編譯時能夠指定參數定製出適合本身企業數據庫

 

1.MySQL官網下載源碼

Archive 存檔檔案文件;檔案室;若是想下載以前的版本;

 

 Community Server 社區版服務端下載 

 

 

 

Archives 存檔  Generic通用 Community 共同體 社區  Poor me ....So I need to learning English and take notes.

 

4、編譯安裝MySQL源碼

1.卸載原MySQL、準備C語言編譯環境

確保本機沒有安裝Maria或者MySQL以後再安裝

rpm -qa | grep mysq
rpm -e --nodeps xx
find / -name mysql
rm -rf 
yum -y install gcc gcc-c++ ncurses ncurses-devel bison cmake make

建立MySQL用戶、組

useradd -M -s /sbin/nologin mysql

建立存放MySQL源碼的目錄

mkdir /opt/

 

2.建立MySQL的源目錄、數據存儲目錄並賦予權限

mkdir /usr/local/mysql/         #/usr/local/mysql/
mkdir /usr/local/mysql/data     #/usr/local/mysql/data
mkdir /usr/local/boost          #/usr/local/boost
chown -R mysql:mysql /usr/local/mysql/*

 

3.編譯安裝

tar -zxvf mysql-5.6.19-linux-glibc2.5-x86_64 -C /opt/
cd /opt/mysql-5.6.19-linux-glibc2.5-x86_64/
 參數說明:
    -DCMAKE_INSTALL_PREFIX=/usr/local/mysql        -----   安裝目錄  這是MySQL的默認安裝位置,而我選擇的是/u01/mysql ,我以爲這樣管理方便,清晰
    -DINSTALL_DATADIR=/usr/local/mysql/data        -----   數據庫存放目錄
    -DDEFAULT_CHARSET=utf8                      -----   使用utf8字符
    -DDEFAULT_COLLATION=utf8_general_ci            -----    校驗字符
    -DEXTRA_CHARSETS=all                        -----    安裝全部擴展字符集
    -DENABLED_LOCAL_INFILE=1                     -----    容許從本地導入數據
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data -DSYSCONFDIR=/etc -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_MEMORY_STORAGE_ENGINE=1 -DWITH_READLINE=1 -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock -DMYSQL_TCP_PORT=3306 -DENABLED_LOCAL_INFILE=1 -DWITH_PARTITION_STORAGE_ENGINE=1 -DEXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci

編譯成功以後就能夠安裝MySQL了;

make install  

在保證下載的是 MySQLSourceCode的狀況下,哪裏報錯就去網上搜解決方案直到你的Linux具有編譯、安裝環境

 

數據庫目錄相關文件說明

[root@localhost data]# ls -lh
total 109M
-rw-rw----. 1 mysql mysql   56 Nov 29 17:17 auto.cnf
-rw-rw----. 1 mysql mysql  12M Nov 30 09:55 ibdata1          #innodb公共表空間文件:存儲個表的數據內容和索引內容。 -rw-rw----. 1 mysql mysql  48M Nov 30 09:55 ib_logfile0      #事物日誌 -rw-rw----. 1 mysql mysql  48M Nov 29 17:00 ib_logfile1      #事物日誌 -rw-r-----. 1 mysql root  7.6K Nov 30 09:59 localhost.localdomain.err  #當前主機主機名+err結尾錯誤日誌
-rw-rw----. 1 mysql mysql    7 Nov 30 09:55 localhost.localdomain.pid  #+err結尾錯誤日誌
drwx------. 2 mysql mysql 4.0K Nov 29 17:00 mysql drwx------.  #MySQL有幾個庫就會有幾個以數據庫命名的文件

2 mysql mysql 4.0K Nov 29 17:02 performance_schema drwxr-xr-x.
2 mysql mysql 20 Nov 29 16:41 test

 

 

4.初始化數據庫 啓動MySQL服務

聲明系統變量就能夠 直接 使用mysql 命令進入數據了

export PATH=/usr/local/mysql/bin:$PATH
/etc/profile.d/mysql.sh
source /etc/profile.d/mysql.sh 
cd /usr/local/mysql
./scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data #初始化數據
[mysqld]
port=3306
basedir=/usr/local/mysql/
datadir=/usr/local/mysql/data
socket=/usr/local/mysql/mysql.sock

!includedir /etc/my.cnf.d
/etc/my.conf

 

刪除匿名和其餘無關用戶

mysql> select user,host,password from user;
+----------+-----------------------+-------------------------------------------+
| user     | host                  | password                                  |
+----------+-----------------------+-------------------------------------------+
| root     | localhost             | *AC241830FFDDC8943AB31CBD47D758E79F7953EA |
| root     | localhost.localdomain |                                           |
| root | 127.0.0.1             |                                           |
| root     | ::1                   |                                           |
| zhanggen | %.%.%.%               | *AC241830FFDDC8943AB31CBD47D758E79F7953EA |
| zhenggen | %.%.%.%               |                                           |
| zhanggen | %                     | *AC241830FFDDC8943AB31CBD47D758E79F7953EA |
| martin   | %                     | *AC241830FFDDC8943AB31CBD47D758E79F7953EA |
+----------+-----------------------+-------------------------------------------+
8 rows in set (0.01 sec)
mysql> delete from mysql.user where user='';
Query OK, 0 rows affected (0.03 sec)
mysql> drop user root@'::1';

 

 

啓動MySQL

[root@localhost zhanggen]# /usr/local/mysql/support-files/mysql.server restart
Shutting down MySQL... SUCCESS! 
Starting MySQL... SUCCESS! 

 進入MySQL

[root@localhost /]# /usr/local/mysql/bin/mysql mysql

 

5.設置建立開發用戶設置密碼並受權

修改root密碼

mysql> set password for root@localhost = password('123'); 
Query OK, 0 rows affected (0.00 sec)

增長開發用戶並受權

mysql>  create user 'martin'@'%' identified by '123.com';
Query OK, 0 rows affected (0.00 sec)

mysql> grant all privileges  on *.* to 'martin'@'%';    
Query OK, 0 rows affected (0.01 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

 

6.MySQL忘記root密碼怎麼辦?

在配置文件中追加2行參數:

skip-grant-tables   #運行本機無密碼訪問
skip-networking     #不容許經過scoket訪問,注意一點要加上不然能夠從外網無密碼鏈接數據庫;

 

7.python自動化批量源碼安裝腳本

須要稍加改造~

import paramiko
ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh._policy = paramiko.AutoAddPolicy()
# print(host,port,username,password)
ssh.connect(hostname='192.168.226.139',port=22, username='root', password='123.com')
stdin,stdout,stderr = ssh.exec_command('rpm -qa | grep mysql')
result = stdout.read().decode('utf-8')

mysql_rpm_list=result.split('\n')
if mysql_rpm_list:
    for rpm in mysql_rpm_list:
        ssh.exec_command('rpm -e --nodeps %s' % (rpm))

stdin,stdout,stderr=ssh.exec_command('find / -name mysql')
result = stdout.read().decode('utf-8')
mysql_path_list=result.split('\n')
if mysql_path_list:
    for path in mysql_path_list:
        ssh.exec_command('rm -rf %s'%(path))

ssh.exec_command('yum -y install gcc gcc-c++ ncurses ncurses-devel bison cmake make')
ssh.exec_command('useradd -M -s /sbin/nologin mysql') # //建立用戶mysql,不建立家目錄,不容許登錄系統
ssh.exec_command('mkdir /opt/')
ssh.exec_command('mkdir /usr/local/mysql/ ') #/usr/local/mysql/
ssh.exec_command('mkdir /usr/local/mysql/data ')  #/usr/local/mysql/data
ssh.exec_command('mkdir /usr/local/boost')        #/usr/local/boost
ssh.exec_command('chown -R mysql:mysql /usr/local/mysql/*')
# transport = paramiko.Transport(('192.168.226.139', 22))
# transport.connect(username='root', password='123.com')
# sftp = paramiko.SFTPClient.from_transport(transport)
# sftp.put('/opt/mysql-5.6.19-linux-glibc2.5-x86_64', '/opt/mysql-5.6.19-linux-glibc2.5-x86_64')
ssh.exec_command('cd /opt/mysql-5.6.19-linux-glibc2.5-x86_64/')
make='cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data -DSYSCONFDIR=/etc -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_MEMORY_STORAGE_ENGINE=1 -DWITH_READLINE=1 -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock -DMYSQL_TCP_PORT=3306 -DENABLED_LOCAL_INFILE=1 -DWITH_PARTITION_STORAGE_ENGINE=1 -DEXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci'
ssh.exec_command(make)
ssh.exec_command('make install')
ssh.exec_command('cd /usr/local/mysql')
ssh.exec_command('./scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data')
#vim /etc/my.conf  [mysqld]
'''
port=3306
basedir=/usr/local/mysql/
datadir=/usr/local/mysql/data
socket=/usr/local/mysql/mysql.sock

'''

#cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
#basedir='/usr/local/mysql/'  datadir='/usr/local/mysql/data'
#/etc/init.d/mysqld start
ssh.close()


import pymysql
db = pymysql.connect("192.168.226.139", "martin", "123.com","mysql")
cursor = db.cursor()
cursor.execute(" show variables like 'max_connections';") #查當前登陸用戶聲明的變量
cursor.execute(" show global variables")                    #查當前全局聲明的變量
cursor.execute("show status like '%Threads_connected%'") #查看MySQL運行狀態 https://www.cnblogs.com/zuxing/articles/7761262.html
print(cursor.fetchall())
# 關閉數據庫鏈接
db.close()
python源碼安裝mysql

 

 

5、MySQL的變量

 無論是show variables 仍是 show status 都區分全局仍是會話級別;

session級別:會話級別的全部設置僅僅對當前會話生效,該會話結束會復原;

mysql> set default_storage_engine=myisam;
Query OK, 0 rows affected (0.08 sec)

mysql> show global variables like '%engin%';
+----------------------------+--------+
| Variable_name              | Value  |
+----------------------------+--------+
| default_storage_engine     | InnoDB |
| default_tmp_storage_engine | InnoDB |
| storage_engine             | InnoDB |
+----------------------------+--------+
3 rows in set (0.01 sec)

mysql> show variables like '%engin%';
+----------------------------+--------+
| Variable_name              | Value  |
+----------------------------+--------+
| default_storage_engine     | MyISAM |
| default_tmp_storage_engine | InnoDB |
| storage_engine             | MyISAM |
+----------------------------+--------+

 

global級別:全局級別全部設置對全部會話生效,可是須要有root權限、對當前會話無效,退出該會話才能生效,MySQL重啓以後復原;

mysql> set global default_storage_engine=innodb;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%engin%';
+----------------------------+--------+
| Variable_name              | Value  |
+----------------------------+--------+
| default_storage_engine     | MyISAM |
| default_tmp_storage_engine | InnoDB |
| storage_engine             | MyISAM |
+----------------------------+--------+
3 rows in set (0.00 sec)

 

 

 查看

mysql> show variables like '%variables_name%';
mysql> select @@variables_name;

設置

set variables_name=value;
set global variables_name=value

 

 

1. 系統變量 show variables

MySQL內部聲明瞭443個系統變量,經過show variables;查看 經過set 這些變量對MySQL的性能進行優化;

innodb_adaptive_flushing={ON|OFF}

設定是否容許MySQL服務器根據工做負載動態調整刷寫InnoDB buffer pool中的髒頁的速率。動態調整刷寫速率的目的在於避免出現IO活動尖峯。默認值爲ON。做用範圍爲全局級別,可用於選項文件,屬動態變量。
 
innodb_adaptive_hash_index={ON|OFF}
設定是否啓用InnoDB的自適應hash索引。基準測試結果顯示,自適應hash索引並不是對全部工做負載都有益,所以須要根據實際應用場景的測試結果選擇更合適的值。此特性默認已啓用,能夠經過命令行選項--skip-innodb_adaptive_hash_index將其禁用。做用範圍是全局,可用於選項文件,屬動態變量。
 
innodb_additional_mem_pool_size={2097152 .. 4294967295}
設定innodb存儲引擎爲了存儲數據字典和其它內部數據結構的內在池大小,單位是字節。表的個數越多,此參數的值就應該設定的越大;當InnoDB用完此內存池的空間,它就會向操做系統申請內存空間,並將向錯誤日誌記錄警告信息。默認大小是8MB。做用範圍爲全局,可用於選項文件,屬非動態變量。
 
innodb_autoextend_increment={1 .. 1000}
當共享表空間沒有多餘的存儲空間時,若是其容許自動增加,此變量可用於設定其單次增加的空間大小,單位是MB,默認值是8。設置了變量innodb_file_per_table的值爲1時InnoDB會爲每張表使用一個單獨的表空間文件,而innodb_autoextend_increment變量不會對此種表空間產生影響。做用範圍爲全局級別,可用於選項文件,屬動態變量。
 
innodb_autoinc_lock_mode={0|1|2}
設定用於生成「自動增加(auto_increment字段)」值的鎖模型。其可接受的值有0、1和2,分別用於表示"traditional"、"consecutive"和"interleaved"鎖模型。默認值爲1。做用範圍爲全局,可用於選項文件,屬非動態變量。
 
innodb_buffer_pool_instances=#
設定將InnoDB的buffer pool分隔爲多少個區域。對於有着數GB空間的buffer pool來講,將其分隔爲多個區域能夠下降不一樣的線程對緩存頁面的讀寫操做時資源爭用係數,進行加強其併發能力。在buffer pool中,讀取或存入頁面時所選擇的區域是基於hash算法隨機進行的。每一個buffer pool管理本身的空閒列表、列表刷寫、LRU以及其它跟buffer pool相關的數據結構,並經過各自的互斥鎖進行保護。
此變量僅在變量innodb_buffer_pool_size的值大於1G時才能發揮功用,緩衝池的總體空間將由各buffer pool實例分割使用。出於最佳效用的目的,建議配合使用innodb_buffer_pool_instances和innodb_buffer_pool_size變量以使得每一個buffer pool實例的都至少有1G的空間。做用範圍爲全局,可用於選項文件,屬非動態變量。
 
innodb_buffer_pool_size=#
設定InnoDB緩存表數據和索引的內存緩衝區大小,單位是字節。其默認值爲128MB,最大值依賴於CPU架構。在一個較繁忙的服務器上,當緩衝池(buffer pool)大於1G時,設定innodb_buffer_pool_instances的值大於1可提其升伸縮能力。innodb_buffer_pool_size變量的值越大,MySQL服務器完成數據訪問時就須要越少的IO,所以,在一個有夠較大內存且爲MySQL服務專用的服務器上,能夠將此值設置爲物理內存的80%。但若是出現以下狀況,建議縮小此變量的值:(1)物理內存資源緊張致使內存頁面換出;(2)InnoDB會爲緩衝和控制結構(buffers and control structures)預留額外的內存,所以事實上其佔用的內存空間可能會比指定的數值大10%左右,這不可能超出對內存資源分配的預估;(3)內存地址空間必須連續,這在基於DLL庫使用特殊地址空間的Windows系統上可能會出現意外狀況;(4)緩衝池的初始化所須要時長與爲其指定的空間大小成正比,例若有10G緩衝池的x86_64的Linux系統上,初始化時間大約要6秒鐘。做用範圍爲全局,可用於選項文件,屬非動態變量。
 
innodb_change_buffering=#
當在表上執行INSERT、UPDATE或DELETE操做時,索引中尤爲是第二索引中的數據未必按序存儲,這就可能引起隨機IO以完成第二索引的更新操做。此變量用來設定InnoDB是否啓用修改緩衝(change buffering)以及使用何種類型的修改緩衝。修改緩衝是一種優化方式,它可以經過延遲寫入操做至第二索引將IO操做轉換爲順序模式。其接受的值有inserts(緩衝insert操做)、deletes(緩衝delete-marking操做)、changes(緩衝insert和delete-marking操做)、purges(緩衝purge操做)、all(緩衝insert、delete-marking和purge操做)和none(不緩衝任何操做)。默認值是all。MySQL 5.5.4以前的版本只接受inserts和none兩種值。做用範圍爲全局,可用於選項文件,屬動態變量。
 
innodb_checksums={ON|OFF}
InnoDB可以使用校驗和(checksum)來驗正從磁盤讀取的全部頁面數據的完整性,從而提升對硬件或數據文件損壞的容錯能力。默認爲啓用,然而,在少數狀況下或許須要禁用這種特性,這能夠經過使用--skip-innodb-checksums命令行選項實現。做用範圍爲全局,可用於選項文件,屬非動態變量。
 
innodb_commit_concurrency={0 .. 1000}
設定InnoDB可同時運行的「提交」操做線程的數量。0表示無限制。此變量不能在運行時將其從「零值」修改成「非零值」,但能夠從一個「非零值」修改成其它值。做用範圍爲全局,可用於選項文件,屬非動態變量。
 
innodb_concurrency_tickets=#
在一個線程進入(enter)InnoDB時,其將會獲取必定數量的「自由卷軸」(free tickets)並憑這些卷軸自由出入InnoDB(即免檢),直到其卷軸耗盡;然後的線程將被置於等待隊列中,並可能須要再次接受併發上限限制檢查。此變量則正是用於設定可同時進入InnoDB的線程併發數,即線程的「自由卷軸」數量。默認值是500。做用範圍爲全局,可用於選項文件,屬動態變量。
 
innodb_data_file_path=IBDATA_FILE
指定InnoDB的各個數據文件及其大小,文件多於一個時彼此間用分號隔開。數據文件路徑能夠爲相對路徑,其相對於innodb_data_home_dir變量所指向的目錄;而文件大小的表示能夠以K(KB)、M(MB)、G(GB)爲單位,但這些文件的大小之和至少要達到10MB。在沒有顯式設定innodb_data_file_path變量的狀況下,MySQL服務器會在數據目錄中自動建立一個可自動增加、初始大小爲10MB的名爲ibdata1的數據文件。單個數據文件的大小上限取決於操做系統,這意味着可使用操做系統所支持的最大單個文件大小覺得其數據文件的體積上限。InnoDB還支持使用裸設備做爲數據文件。做用範圍爲全局,可用於選項文件,屬非動態變量。
 
innodb_data_home_dir=/PATH/TO/DIR
InnoDB全部共享表空間數據文件的目錄路徑。默認值爲MySQL的數據目錄。能夠將此變量的值設置爲空,而後在innodb_data_file_path中爲每一個數據文件使用絕對路徑。此變量不影響變量innodb_file_per_table啓用狀態下的每表表空間的數據文件。做用範圍爲全局,可用於選項文件,屬非動態變量。
 
innodb_doublewirte={ON|OFF}
設定InnoDB是否使用雙寫緩衝。默認爲啓用。InnoDB在對頁面進行部分寫入的時候使用雙寫緩衝,以防止數據損壞。雙寫緩衝是表空間中一個特殊的保留區域,其大小足夠在一個連續區間容納100個頁面。當InnoDB把頁面從緩衝池刷寫至磁盤時,它會先把這些頁面刷到雙寫緩衝中,而後再保存至真正的目標位置。所以,雙寫緩衝本質上是最近寫入頁面的備份,其可確保每次寫入的原子性和可持續性。在有些狀況下雙寫緩衝是沒必要要的,例如在從服務器上就能夠將之禁用;此外,一些文件系統(如ZFS)自身也會實現此功能,那麼InnoDB就不用作重複的工做了。做用範圍爲全局,可用於選項文件,屬非動態變量。
 
innodb_fast_shutdown={0|1|2}
設定InnoDB關閉模式。其可接受的值中,「0」表示慢速關閉,這意味着InnoDB關閉以前會完成徹底清寫(full purge)和修改緩衝合併(insert buffer merge)操做;「1」是默認值,它表示InnoDB在關閉時會跳過模式0中進行的這些操做,這也是其之因此稱做「快速關閉」的緣由;「2」表示InnoDB僅刷寫日誌信息並執行冷(cold)關閉,此時並無事務丟失,只是下次啓動MySQL服務時須要花費較長的時間進行故障恢復(crash recovery)。
執行慢速關閉時其過程可能會持續數分鐘的時間,甚至在有些極端狀況下,好比有着大量數據緩衝的場景,此過程時長會以小時來計。通常狀況下僅在對MySQL進行主版本升級時才須要進行慢速關閉以使得數據文件可以爲徹底適應新版本而準備穩當。一般也只能遇到緊急情況或出於調試的目的才須要將此變量的值設定爲2,以便讓處於有可能損壞風險中的數據執行最快速度的關閉。做用範圍爲全局,可用於選項文件,屬動態變量。
 
innodb_file_format={Antelope|Barracuda}
設定新建InnoDB表的文件格式。其可接受的參數有Antelope和Barracuda,但這僅對基於變量innodb_file_per_file的每表表空間文件有影響。某些InnoDB特性如表壓縮功能僅有Barracuda文件格式支持。做用範圍爲全局,可用於選項文件,屬動態變量。
 
innodb_file_format_check={ON|OFF}
用於設定InnoDB是否在MySQL服務器啓動時檢查共享表空間的文件格式標籤。檢查標籤時若是其高於當前InnoDB版本所支持的能力,InnoDB就會產生錯誤並拒絕啓動;不然,對MySQL 5.5.5 及後來的版原本說InnoDB則會設置變量innodb_file_format_max的值爲共享表空間的文件格式標籤,而對於MySQL 5.5.5以前的版原本說,InnoDB會將共享表空間的文件格式設置爲變量innodb_file_format_check的值。做用範圍爲全局,可用於選項文件,屬非動態變量。
 
innodb_file_format_max={Antelope|Barracuda}
在MySQL服務啓動時,InnoDB會將變量innodb_file_format_max的值設置爲共享表空間的文件格式標籤(好比,Antelope或Barracuda)。若是MySQL服務器建立或打開了一個有着更高級格式的表,此變量的值則會被設置爲那個更高級的格式。做用範圍爲全局,可用於選項文件,屬動態變量。
 
innodb_file_per_table={ON|OFF}
設定InnoDB表是否使用每表表空間數據文件(以.ibd結尾)分別存儲每一個表的數據和索引。若是使用了每表表空間數據文件,其將再也不使用系統表空間(即共享表空間)。InnoDB表的某些特性,如壓縮表等僅對每表表空間生效。做用範圍爲全局,可用於選項文件,屬動態變量。
 
innodb_flush_log_at_trx_commit={0|1|2}
設定InnoDB同步日誌緩衝區(log buffer)數據至日誌文件中的方式,以及刷寫日誌文件至磁盤的方式。其可接受的值中,「0」表示將日誌緩衝區每秒一次地寫入日誌文件,並同時將日誌文件刷寫至磁盤中,但事務提交時不會採起任何動做;「1」是默認值,表示在有事務提交時將日誌緩衝區寫入日誌文件,並同時將日誌文件刷寫至磁盤;「2」表示每事務提交或每秒一次將日誌緩衝區寫入日誌文件,但不會同時執行日誌文件的刷寫操做。固然,因爲操做系統進程調度的緣由,每秒一次的日誌寫入或刷寫操做並不能獲得100%的保證。
徹底兼容ACID的場景須要將此變量值設置爲1,因爲要執行每事務的日誌刷寫操做,其會阻止I/O調用,直到寫操做完成,故其會顯著下降InnoDB每秒鐘能夠提交的事務數。設置爲「2」可得到比「1」更好的性能,並且僅在操做系統崩潰時纔會丟失最後一秒鐘的數據,所以數據安全性也有着不錯的表現。設置爲「0」則有可能會致使事務最後一秒鐘的數據丟失,因而整個事務的數據安全性將沒法保證,但其一般有着最好的性能。爲了在最大程序上保證複製的InnoDB事務持久性和一致性,應該設置變量innodb_flush_log_at_trx_commit=1以及設置變量sync_binlog=1。
然而須要注意的是,有些磁盤自身也有緩存,這可能會給事務操做帶來額外的潛在風險。可使用hdparm工具或供應商的自有工具等禁用磁盤自身的緩存。固然,高性能事務的最佳配置是把此變量的值設置爲1,而且將日誌文件放在有備用電池的寫入緩存的RAID上。做用範圍爲全局,可用於選項文件,屬動態變量。
 
innodb_flush_method={O_DSYNC|O_DIRECT}
設定InnoDB實際與文件系統進行交互的方式。除了寫操做以外,它還能夠影響InnoDB如何讀取數據。設置innodb_flush_method變量的值爲O_DSYNC時,InnoDB使用O_SYNC標誌來打開和刷寫日誌文件,而使用fsync()來刷寫數據文件。O_SYNC會使得全部的寫入操做都是同步的,即只有在數據被寫入磁盤以後纔會返回,但不會在操做系統層面禁止緩存,所以,它不會避免雙緩衝,而且不會直接寫入磁盤。fsync()會同時刷數據和元數據(而fdatasync()只刷寫數據),它比fdatasync()產生更多的IO操做,並且操做系統會緩存一些數據在本身的緩存中(這將致使雙緩衝)。如文件系統能夠智能地處理I/O需求,雙緩衝可能不是壞事兒,但若是MySQL設置了innodb_file_per_table變量的值爲1,則會致使第個表空間文件都單獨使用fsync()函數,其寫入操做就不可能會被合併了。
設置innodb_flush_method變量的值爲O_DIRECT時,InnoDB使用O_DIRECT標誌打開數據文件,而使用fsync()刷寫數據和日誌文件。O_DIRECT標誌會致使操做系統既不緩存數據,也不預讀數據,它徹底禁止了操做系統的緩存而且使全部的讀寫動做直接至存儲設備,避免了雙緩衝。然而,其不能禁止硬件層面(如RAID卡)的緩存和預讀功能,並且啓用硬件層面的緩存和預讀功能也是保證InnoDB使用了O_DIRECT標誌時仍能保持良好性能的唯一途徑。
做用範圍爲全局,可用於選項文件,屬非動態變量。
 
innodb_force_load_corrupted={ON|OFF}
設定InnoDB在啓動時是否裝載標記爲「已損壞(corrupted)」的表。僅應該在troubleshooting的場景中啓用該功能以修復沒法訪問的表,在troubleshooting任務完成後應該禁用此功能並重啓MySQL服務。做用範圍爲全局,可用於選項文件,屬非動態變量。
 
innodb_force_recovery={0|1|2|3|4|5|6}
設定InnoDB的故障恢復模式。InnoDB出現了「頁面損壞(page corruption)」時,一般大部分數據仍然無缺,因而能夠經過SELECT...INTO OUTFILE命令備份出數據以下降損失程度。然而,某些「損壞」類的故障可能會致使SELECT * FROM tbl_name命令沒法執行或InnoDB後臺操做崩潰,甚至會致使InnoDB的前滾操做。這種狀況下,就可使用innodb_force_recovery變量強制InnoDB存儲引擎在啓動時不執行後臺操做,以便能將數據備份出來。
innodb_force_recovery可接受的值中,「0」爲默認值,表示執行正常啓動,即不啓用「強制修復」模式。而非零值中,某數值會包含比其小的全部數值的預防措施,然而其也較可能給B-tree索引及其它的數據結構帶來更多的損壞。故此,在此變量值爲非零值時,其會阻止用戶使用INSERT、UPDATE或DELETE操做,可是會容許執行SELECT、CREATE TABLE或DROP TABLE類的操做。如下是關於其它非零值功能的說明:
1(SRV_FORCE_IGNORE_CORRUPT):即便出現了頁面損壞也照常運行MySQL服務,其會在SELECT * FROM tbl_name語句執行時嘗試跳過損壞的索引記錄和頁面。
2(SRV_FORCE_NO_BACKGROUND):禁止啓動主線程(master thread),其會在執行清寫(purge)操做時防止出現崩潰(crash)。
3(SRV_FORCE_NO_TRX_UNDO):在故障恢復(crash recovery)後不執行事務的回滾操做。
4(SRV_FORCE_NO_IBUF_MERGE):禁止執行修改緩衝(insert buffer)合併操做。
5(SRV_FORCE_NO_UNDO_LOG_SCAN):在啓動數據庫服務時不檢查撤消日誌(undo logs),這會致使InnoDB將未完成的事務視爲已提交。
6(SRV_FORCE_NO_LOG_REDO):不執行重作日誌(redo log)的前滾操做。此時,僅能執行不帶WHERE、ORDER BY或其它子句的SELECT * FROM tbl_name操做,由於複雜查詢在遇到損壞的數據結構時會停止並退出。
 
innodb_io_capacity=#
設定InnoDB後臺任務(如從緩衝池刷寫頁面或合併修改緩衝中的數據等)可執行的I/O操做上限。其最小值爲100,默認值爲200,最大值取決於CPU架構。對於有着較大I/O負載的服務器來說,應該爲其指定更大的值以便可以更好更快的執行後臺維護任務。然而,在實踐中,此變量的值應該儘量接近MySQL服務器每秒鐘執行的I/O操做數量(即IOPS),甚至於讓其低至以不影響後臺任務執行爲目標的最低限度。由於,若是此值太高的話,數據會被頻繁地從緩衝中移入移出,這會下降緩存池的在系統性能提高方面的效用。單個5400RPM或7200RPM磁盤僅能完成大約100個IOPS,所以,此種狀況下應該將此變量值下降至100;而對於有着多塊磁盤或更強性能的存儲設備(如固態磁盤)的應用場景,能夠按需提升此變量的值。做用範圍爲全局,可用於選項文件,屬動態變量。
 
innodb_large_prefix={ON|OFF}
設定對於使用了DYNAMIC或COMPRESSED行格式的InnoDB表來講,是否可以使用大於767字節長度的索引前綴。然而,建立此種類型的表還須要設定innodb_file_format的值爲barracuda,以及innodb_file_per_table的值爲ture。同時,此設定對使用了REDUNDANT和COMPACT行格式的表的索引長度限定來講是不起做用的。做用範圍爲全局,可用於選項文件,屬動態變量。
 
innodb_lock_wait_timeout={1 .. 1073741824}
設定InnoDB中某事務試圖訪問一個由其它InnoDB事務加鎖的行時其最長的等待時間,單位爲秒鐘,默認值爲50。在超時狀況發生時,InnoDB會返回一個1205類型的錯誤信息,並對當前語句(非整個事務)執行回滾操做;若是須要在此種狀況下對整個事務進行回滾,則須要在MySQL服務啓動時使用--innodb_rollback_on_timeout選項。
對於OLTP系統或有着較多交互式應用的程序來講,應該下降此變量值以使得用戶較快地獲取到反饋信息,或使得系統較塊地將此更新操做提交到隊列中以便延後處理。對於批處理應用較多的場景來講,如數據倉庫,應該增長此變量的值以等待其它較大的插入或更新操做完成。
此變量僅對InnoDB的行鎖產生做用,MySQL的表鎖並不是在InnoDB中實現,因此此超時時長對錶鎖沒有影響。並且,因爲InnoDB會能當即探測到死鎖的發生並會對其中的一修整務執行回滾操做,所以此超時時長也不該用於死鎖。做用範圍爲全局或會話級別,可用於選項文件,屬動態變量。
 
innodb_locks_unsafe_for_binlog={ON|OFF}
設定InnnoDB是否在搜索和索引掃描中使用間隙鎖(gap locking)。InnoDB使用行級鎖(row-level locking),一般狀況下,InnoDB在搜索或掃描索引的行鎖機制中使用「下一鍵鎖定(next-key locking)」算法來鎖定某索引記錄及其前部的間隙(gap),以阻塞其它用戶緊跟在該索引記錄以前插入其它索引記錄。站在這個角度來講,行級鎖也叫索引記錄鎖(index-record lock)。
默認狀況下,此變量的值爲OFF,意爲禁止使用非安全鎖,也即啓用間隙鎖功能。將其設定爲ON表示禁止鎖定索引記錄前的間隙,也即禁用間隙鎖,InnoDB僅使用索引記錄鎖(index-record lock)進行索引搜索或掃描,不過,這並不由止InnoDB在執行外鍵約束檢查或重複鍵檢查時使用間隙鎖。
啓用innodb_locks_unsafe_for_binlog的效果相似於將MySQL的事務隔離級別設定爲READ-COMMITTED,但兩者並不徹底等同:innodb_locks_unsafe_for_binlog是全局級別的設定且只能在服務啓動時設定,而事務隔離級別可全局設定並由會話級別繼承,然而會話級別也以按需在運行時對其進行調整。相似READ-COMMITTED事務隔離級別,啓用innodb_locks_unsafe_for_binlog也會帶來「幻影問題(phantom problem)」,但除此以外,它還能帶來以下特性:
(1)對UPDATE或DELETE語句來講,InnoDB僅鎖定須要更新或刪除的行,對不可以被WHERE條件匹配的行施加的鎖會在條件檢查後予以釋放。這能夠有效地下降死鎖出現的機率;
(2)執行UPDATE語句時,若是某行已經被其它語句鎖定,InnoDB會啓動一個「半一致性(semi-consistent)」讀操做從MySQL最近一次提交版本中得到此行,並以之斷定其是否可以並當前UPDATE的WHERE條件所匹配。若是可以匹配,MySQL會再次對其進行鎖定,而若是仍有其它鎖存在,則須要先等待它們退出。
 
innodb_log_buffer_size={262144 .. 4294967295}
設定InnoDB用於輔助完成日誌文件寫操做的日誌緩衝區大小,單位是字節,默認爲8MB。較大的事務能夠藉助於更大的日誌緩衝區來避免在事務完成以前將日誌緩衝區的數據寫入日誌文件,以減小I/O操做進而提高系統性能。所以,在有着較大事務的應用場景中,建議爲此變量設定一個更大的值。做用範圍爲全局級別,可用於選項文件,屬非動態變量。
 
innodb_log_file_size={108576 .. 4294967295}
設定日誌組中每一個日誌文件的大小,單位是字節,默認值是5MB。較爲明智的取值範圍是從1MB到緩存池體積的1/n,其中n表示日誌組中日誌文件的個數。日誌文件越大,在緩存池中須要執行的檢查點刷寫操做就越少,這意味着所需的I/O操做也就越少,然而這也會致使較慢的故障恢復速度。做用範圍爲全局級別,可用於選項文件,屬非動態變量。
 
innodb_log_files_in_group={2 .. 100}
設定日誌組中日誌文件的個數。InnoDB以循環的方式使用這些日誌文件。默認值爲2。做用範圍爲全局級別,可用於選項文件,屬非動態變量。
 
innodb_log_group_home_dir=/PATH/TO/DIR
設定InnoDB重作日誌文件的存儲目錄。在缺省使用InnoDB日誌相關的全部變量時,其默認會在數據目錄中建立兩個大小爲5MB的名爲ib_logfile0和ib_logfile1的日誌文件。做用範圍爲全局級別,可用於選項文件,屬非動態變量。
 
innodb_max_dirty_pages_pct={0 .. 99}
設定InnoDB的緩衝池中髒頁比例的上限,默認爲75。當緩存池中的髒頁比例接近或達到此變量定義的比值時,InnoDB的主線程會將刷寫部分髒頁中的數據至對應的文件中。做用範圍爲全局級別,可用於選項文件,屬動態變量。
 
innodb_max_purge_lag={0 .. 4294967295}
InnoDB事務系統會維持一個有索引記錄被添加了刪除標記(delete-marked)的事務的列表,此列表的長度即爲清寫延遲(purge_lag)。此變量用於設定當發生清寫延遲時,其隊列長度達到多大時開始延遲INSERT、UPDATE或DELETE操做。當puge_lag超過innodb_max_purge_lag時,將延遲這些操做((purge_lag/innodb_max_purge_lag)*10)-5毫秒。默認值爲0,表示從不延遲這些操做。須要進行操做延遲與否是在purge操做剛開始時計算的,而且每隔10秒鐘會從新計算一次。基於歷史地緣由,purge操做沒法啓動時是不會有任何操做延遲的狀況發生。做用範圍爲全局級別,可用於選項文件,屬動態變量。
 
innodb_mirrored_log_groups=#
設定日誌組鏡像的個數。其值應該爲1。
 
innodb_old_blocks_pct={5 .. 95}
InnoDB以「列表」結構管理緩存池,並使用修改版的LRU算法對其執行維護操做。當須要空間以保存新塊(new block)時,InnoDB會清理最近最少使用的塊並將新塊加入到列表中。「中點插入策略(midpoint insertion policy)」將整個列表看做兩個子列表:在列表首部是那些最近被訪問過的新塊(new/young block)子列表,尾部是那些最近較少被訪問到的舊塊(lod block)子列表。而LRU算法和中點插入策略用於保證將最近常常被訪問到的塊置於新塊子列表,InnoDB新讀入的塊將被置於舊塊子列表的前頭,並根據須要將舊塊子列表中的塊移除。而某個被再次訪問到的舊塊則會被移至新塊子列表的首部。表掃描操做可能會一次性地向緩存池中讀入大量的數據塊並可能致使一大批舊塊被移出。
此變量正是用於設置被視做舊塊子列表的長度所佔據整個列表長度的比例,默認值是37,即緩存池的八分之三。做用範圍爲全局級別,可用於選項文件,屬動態變量。
 
innodb_old_blocks_time=#
用於設定緩衝池中舊塊子列表中的某舊塊在其第一次又被訪問到時,其至少須要在舊塊子列表中再呆上多長時間(單位爲毫秒)纔會被轉移至新塊子列表。默認值是0,表示當即轉移至新塊子列表,哪怕其剛剛被轉移至舊塊子列表。而非零值則明肯定義舊塊列表中的塊在其第一次被訪問到時至少須要在舊塊子列表中等待轉移的時長。此變量一般要結合innodb_old_blocks_pct使用。做用範圍爲全局級別,可用於選項文件,屬動態變量。
 
innodb_open_files=#
設定MySQL可同時打開的.ibd表空間文件的數量上限。此變量僅在使用多表空間文件時生效,其最小值爲10,默認值爲300。此變量的限定僅應用於InnoDB表的.ibd文件,跟MySQL服務器選項--open-files-limit沒有關係,更不會影響表緩存的操做。做用範圍爲全局級別,可用於選項文件,屬非動態變量。
 
innodb_purge_batch_size={1 .. 5000}
清寫(purge)是指將緩存池中的髒頁同步至持久性存儲設備中的操做,以重作日誌的記錄爲單位。此變量則用於定義清寫操做的粒度,即多少個重作日誌記錄組合起來能夠觸發一次清寫操做,默認值爲20。此變量一般用於跟innodb_purge_threads=1一塊兒對進行性能調優,但通常場景中都不須要修改它。做用範圍爲全局級別,可用於選項文件,屬非動態變量。
 
innodb_purge_threads={0|1}
設定InnoDB執行清寫操做的線程數量。默認值爲0,表示清寫操做由InnoDB的主線程本身完成,這能夠下降內部資源競爭發生的機率,進而加強MySQL服務伸縮能力。不過,隨着InnoDB內部各式各樣的競爭愈來愈多,這種設置帶來的性能優點已幾乎不值一提。做用範圍爲全局級別,可用於選項文件,屬動態變量。
 
innodb_read_ahead_threshold={0 .. 64}
設定InnoDB預讀頁面至緩衝池時的線性預讀敏感度,也即InnoDB的讀操做至少從一個盤區(extent,包含64個頁面)中讀取多個頁面時纔會爲讀取整個盤區中後續的頁面初始化一個異步讀操做。默認值爲56。做用範圍爲全局級別,可用於選項文件,屬動態變量。
 
innodb_read_io_threads={1 .. 64}
設定InnoDB爲讀操做啓動的I/O線程數量,默認爲4個。做用範圍爲全局級別,可用於選項文件,屬非動態變量。
 
innodb_replication_delay={0 .. 4294967295}
設定在從服務器(slave)上運行的線程數達到innodb_thread_concurrency變量定義的併發上限時複製線程須要延遲的時長。默認爲0,表示不延遲。做用範圍爲全局級別,可用於選項文件,屬動態變量。
 
innodb_rollback_on_timeout={ON|OFF}
設定事務執行過程超時時事務回滾的方式。在MySQL 5.5中,默認爲OFF,表示僅回滾事務中的最後一個語句。若是設置爲ON,則表示停止事務執行並回滾整個事務。做用範圍爲全局級別,可用於選項文件,屬非動態變量。
 
innodb_rollback_segments={1 .. 128}
設定InnoDB在系統表空間中爲每一個事務使用多少個回滾段(rollback segment),默認爲128個。若是較少的回滾段能夠提高系統性能,則應該下降此變量的值。做用範圍爲全局級別,可用於選項文件,屬動態變量。
 
innodb_spin_wait_delay={0 .. 4294967295}
自旋(spin)是一種經過不間斷地測試來查看一個資源是否變爲可用狀態的等待操做,用於僅須要等待很短的時間等待所需資源的場景。使用自旋這種「空閒循環(busy-loop)」來完成資源等待的方式要比經過上下文切換使線程轉入睡眠狀態的方式要高效得多。但若是自旋了一個很短的時間後其依然沒法獲取資源,則仍然會轉入前述第二種資源等待方式。此變量則正是用於定義InnoDB自旋操做的空閒循環轉數,默認爲6轉。做用範圍爲全局級別,可用於選項文件,屬動態變量。
 
innodb_stats_method={nulls_equal|nulls_unequal|null_ignored}
設定MySQL爲InnoDB表收集分佈的索引值的統計數據時如何處理NULL類型的數據。其可接受的值有三個,null_equals意指將全部的NULL值視爲相同,併爲之建立一個值組(value group)以保存NULL類值的個數;nulls_unequal意指將全部的NULL值視爲不一樣,併爲每一個NULL單首創建一個大小爲1的值組;nulls_ignored表示全部的NULL值都被忽略。這些用於生成表統計數據的方法會影響到優化器爲執行查詢如何選擇選擇索引。做用範圍爲全局級別,可用於選項文件,屬動態變量。
 
innodb_stats_on_metadata={OFF|ON}
設定使用SHOW TABLE STATUS或者SHOW INDEX這兩個元數據語句時,或訪問INFORMATION_SCHEMA中的TABLES或STATISTICS表時,InnoDB是否更新統計數據。默認爲更新。禁用此功能能夠加速訪問有着大量的表或索引的數據庫,也可能提高InnoDB表上查詢操做執行計劃(execution plan)的穩定性。做用範圍爲全局級別,可用於選項文件,屬動態變量。
 
innodb_strict_mod={ON|OFF}
爲防止無視SQL語句書寫或語法中的錯誤或無視操做模式與SQL語句各類組合中的無意之過,InnoDB提供了所謂的嚴格模式。嚴格模式中,前述的問題一旦出現將會致使InnoDB產生一個錯誤,而非警告和一系列特定的處理操做。此參數則正是用於定義是否啓用InnoDB的嚴格模式,默認爲OFF。
 
innodb_support_xa={TRUE|FLASE}
存儲引擎事務在存儲引擎內部被賦予了ACID屬性,分佈式(XA)事務是一種高層次的事務,它利用「準備」而後「提交」(prepare-then-commit)兩段式的方式將ACID屬性擴展到存儲引擎外部,甚至是數據庫外部。然而,「準備」階段會致使額外的磁盤刷寫操做。XA須要事務協調員,它會通知全部的參與者準備提交事務(階段1)。當協調員從全部參與者那裏收到「就緒」信息時,它會指示全部參與者進行真正的「提交」操做。
此變量正是用於定義InnoDB是否支持兩段式提交的分佈式事務,默認爲啓用。事實上,全部啓用了二進制日誌的並支持多個線程同時向二進制日誌寫入數據的MySQL服務器都須要啓用分佈式事務,不然,多個線程對二進制日誌的寫入操做可能會以與原始次序不一樣的方式完成,這將會在基於二進制日誌的恢復操做中或者是從服務器上建立出不一樣原始數據的結果。所以,除了僅有一個線程能夠改變數據之外的其它應用場景都不該該禁用此功能。而在僅有一個線程能夠修改數據的應用中,禁用此功能是安全的並能夠提高InnoDB表的性能。做用範圍爲全局和會話級別,可用於選項文件,屬動態變量。
 
innodb_sync_spin_loops={0 .. 4294967295}
設定一個線程在等待InnoDB釋放某個互斥量(mutex)以前自旋的轉數,當自旋操做達到這個轉數但互斥量仍未被釋放時此線程將被掛起。默認值爲30。做用範圍爲全局級別,可用於選項文件,屬動態變量。
 
innodb_table_locks={ON|OFF}
InnoDB在存儲引擎級別支持行級鎖,而MySQL在服務器級別還支持使用表級鎖。此變量則正是用來定義InnoDB是否在其內部支持使用MySQL表級鎖。默認值爲1或ON,表示若是autocommit變量的值爲0(即禁止自動提交),在InnoDB表上顯式使用LOCK TABLES語句將使得InnoDB在存儲引擎內部鎖定此表。使用0或OFF值,則意味着顯式使用LOCKS TABLE...WRITE語句不會在存儲引擎級別產生影響,但對其它顯式使用的LOCK TABLES...WRITE或LOCK TABLES...READ語句依然會有影響。做用範圍爲全局和會話級別,可用於選項文件,屬動態變量。
 
innodb_thread_concurrency={0...1000}
設定InnoDB可在其內部併發運行的操做系統線程數量上限。多出的線程將被放置於FIFO隊列進行等待,且不被計入併發運行線程數量。對於不用的應用場景來講,其理想的取值取決於硬件環境和工做負載,通常推薦爲CPU個數的2倍加上磁盤的個數。默認值爲0,表示無上限(不檢查併發數量),這意味着InnoDB能夠按須要使用任意數量的併發線程,並會禁用SHOW ENGINE INNODB STATUS中的queries inside InnoDB和queries in queue counters兩個計數器。做用範圍爲全局級別,可用於選項文件,屬動態變量。
 
innodb_thread_sleep_delay=#
設定InnoDB線程在加入InnoDB隊列以前的睡眠時長,單位是毫秒,默認值爲10000。0值表示禁止睡眠而直接加入隊列。做用範圍爲全局級別,可用於選項文件,屬動態變量。
 
innodb_use_native_aio={ON|OFF}
設定InnoDB是否使用Linux的異步I/O子系統,所以,其僅應用於Linux系統平臺,且MySQL啓動後不能更改其值。InnoDB默認會啓用此功能,而InnoDB若是由於Linux的異步I/O子系統的問題而沒法正常啓動,能夠在選項文件中將此變量設置爲OFF並從新啓動之。事實上,就算變量值爲ON,若是MySQL服務啓動探測到了潛在的問題如聯合的臨時目錄路徑、tmpfs文件系統以及Linux內核不支持在tmpfs上使用AIO機制時也會自動關閉此變量。做用範圍爲全局級別,可用於選項文件,屬非動態變量。
 
innodb_use_sys_malloc={ON|OFF}
設定InnoDB使用操做系統的(ON)仍是自有的(OFF)內存分配器。默認值爲ON。
 
innodb_version=STRING
InnoDB存儲引擎的版本號,只讀變量。
 
innodb_write_io_threads={1 .. 64}
設定InnoDB用於完成寫操做的I/O線程數量,默認爲4個。
 
 
附:InnoDB的數據字典指的是跟蹤InnoDB相關的對象如表、索引或表中的字段等的元數據信息,這些元數據存儲在InnoDB的系統表空間中(system tablespace)。歷史地緣由,它跟.frm文件中的某些數據有重疊的地方。
常見變量說明

若是想查看MySQL相關的某些屬性可使用 like ''%屬性% ''進行模糊匹配;

mysql> show variables like '%屬性名稱%';
mysql> show variables like '%data%';
+-------------------------------+------------------------+
| Variable_name                 | Value                  |
+-------------------------------+------------------------+
| character_set_database        | utf8                   |
| collation_database            | utf8_general_ci        |
| datadir                       | /usr/local/mysql/data/ |
| innodb_data_file_path         | ibdata1:12M:autoextend |
| innodb_data_home_dir          |                        |
| innodb_stats_on_metadata      | OFF                    |
| max_length_for_sort_data      | 1024                   |
| metadata_locks_cache_size     | 1024                   |
| metadata_locks_hash_instances | 8                      |
| myisam_data_pointer_size      | 6                      |
| skip_show_database            | OFF                    |
| updatable_views_with_limit    | YES                    |
+-------------------------------+------------------------+
12 rows in set (0.00 sec)
data相關
mysql> show variables like '%engin%';
+----------------------------+--------+
| Variable_name              | Value  |
+----------------------------+--------+
| default_storage_engine     | InnoDB |
| default_tmp_storage_engine | InnoDB |
| storage_engine             | InnoDB |
+----------------------------+--------+
3 rows in set (0.00 sec)
數據庫引擎相關

 

 

 2.運行狀態變量show status

 能夠經過show status,查看MySQL的運行狀態的相關變量來了解MySQL的相關狀態,做爲開發人員咱們能夠把這些數據分析展現給DBA;

 

 6、MySQL日誌

MySQL的日誌分爲如下幾類:

錯誤日誌:記錄錯誤信息(運維關心)

查詢日誌:記錄用戶執行的SQL語句

慢查詢日誌:記錄執行速度慢的SQL的

事物日誌

二進制日誌

中繼日誌

 

1.查詢日誌

查詢日誌是記錄用戶輸入SQL,不只能夠記錄到文件,還能夠輸出到表中,知道怎麼跑路了嗎?小夥?

開啓查詢日誌功能

mysql> set global general_log=on;      #開啓查詢日誌功能
Query OK, 0 rows affected (0.08 sec)

mysql> set global log_output='table'; #設置查詢日誌輸出到表中

只有你開啓了查詢日誌功能並指定了日誌的輸出MySQL就會把數據輸出到表(MySQL庫中的general_log表)或配置的log文件中

mysql> select * from general_log;

 

 2.慢查詢日誌

在你設置一個慢查時長以後,若是SQL從開始<---->結束執行所花費的時間大於該時間,那麼慢日誌記錄該SQL;

這些慢日誌對於DBA來講很是有價值,它們就是基於這些作SQL優化的;

 

查看默認設置的慢日誌時間閥值(10秒能夠精確到微秒)

mysql> show global variables like '%long%';
+--------------------------------------------------------+-----------+
| Variable_name                                          | Value     |
+--------------------------------------------------------+-----------+
| long_query_time                                        | 10.000000 |
| performance_schema_events_stages_history_long_size     | 10000     |
| performance_schema_events_statements_history_long_size | 10000     |
| performance_schema_events_waits_history_long_size      | 10000     |
+--------------------------------------------------------+-----------+
4 rows in set (0.02 sec)
set global slow_query_log=on; #開啓記錄慢查詢日誌功能

 若是設置了log_output =TABLE,MySQL的慢查日誌存在mysql庫的slow_log表;

mysql> select * from slow_log;

 

 3.事物日誌

MySQL的innodb搜素引擎才支持事物,須要注意:全部的事物操做都不會當即同步到數據庫執行,而是先記錄到事物日誌文件;因爲事物日誌按期向數據庫提交;

事物日誌須要至少2文件記錄提交事物,這兩個文件是輪轉的,1個寫滿寫另外一個;

mysql> show global variables like '%innodb_log%';
+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| innodb_log_buffer_size      | 8388608  |  #
| innodb_log_compressed_pages | ON       | 
| innodb_log_file_size        | 50331648 |  #事物日誌的大小
| innodb_log_files_in_group   | 2        |  #指定事物日誌文件個個數
| innodb_log_group_home_dir   | ./       |  #innodb事物日誌所在的目錄 
+-----------------------------+----------+
5 rows in set (0.01 sec)

| innodb_flush_log_at_trx_commit #一旦事物提交同步到事物日誌,1=每隔1秒鐘同步1次,不管是否提交事物;2=只有事物提交才同步

 

4.二進制日誌

4.1 什麼是二進制日誌文件?

記錄修改數據或者有可能引發數據修改的SQL語句,因此select語句是不會記錄進來的;

 

4.2 什麼是主從複製?

那麼S數據庫不斷得讀取並執行M數據庫產生的二進制個文件,致使S數據庫=M數據庫,這種技術手段就是主從複製;

 

4.3 MySQL二進制的格式有哪些?

若是 Master執行SQL包含獲取當前時間的函數,Save再去經過二進制日誌執行中間的時差勢必會致使數據庫不一致,因此僅記錄SQL語句是不能完成主從複製的;還須要記錄數據;

 

二進制日誌格式有如下3種

SQL語句:statement

行數據:row

 混合:mixed

 

4.4 開啓二進制日誌

log-bin=mysql-bin               #開啓二進制日誌
server-id = 1                   #主數據庫id爲1,不能相同。
replicate_wild_do_table=web.%  #只同步test庫下的表
/etc/my.conf
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+
1 row in set (0.07 sec)

 

 4.5 查看當前MySQL的二進制日誌

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       120 |
+------------------+-----------+

 查看主

mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       120 |
+------------------+-----------+
1 row in set (0.01 sec)

 

執行flush logs操做會生成一個新的binlog文件

mysql> flush logs;
Query OK, 0 rows affected (0.03 sec)

 

 

查看當前使用的二進制日誌

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      120 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)

 

 

查看二進制日誌事件

mysql> show binlog events in 'mysql-bin.000001';
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------------------------------------------+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                                                              |
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------------------------------------------+
| mysql-bin.000001 |   4 | Format_desc |         1 |         120 | Server ver: 5.6.19-log, Binlog ver: 4                                             |
| mysql-bin.000001 | 120 | Query       |         1 |         241 | create database python default charset=utf8                                       |
| mysql-bin.000001 | 241 | Query       |         1 |         386 | use `python`; create table t5 (id int auto_increment primary key,name varchar(9)) |
| mysql-bin.000001 | 386 | Query       |         1 |         469 | BEGIN                                                                             |
| mysql-bin.000001 | 469 | Query       |         1 |         591 | use `python`; insert into t5(id,name) values(1,"zhanggen")                        |
| mysql-bin.000001 | 591 | Xid         |         1 |         622 | COMMIT /* xid=22 */                                                               |
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------------------------------------------+
6 rows in set (0.00 sec)

 

 

 4.6 經過sql_log_bin控制會話級別臨時開啓關閉記錄二進制功能;

在數據庫恢復的時候 臨時關閉二進制文件記錄功能,是爲了排除恢復過程當中產生的SQL寫入二進制文件;

mysql> set sql_log_bin='OFF';
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%sql_log_bin%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_log_bin   | OFF   |
+---------------+-------+
1 row in set (0.00 sec)

mysql> set sql_log_bin='on';
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%sql_log_bin%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_log_bin   | ON    |
+---------------+-------+
1 row in set (0.00 sec)

 

4.7 mysqlbinlog 

mysqlbinlog 是mysql自帶的二進制日誌管理工具,利用它的截取功能能夠基於徹底備份的數據+二進制日誌,作徹底備份時間節點以後任意時間的數據恢復工做了;

 

使用mysqlbinlog 截取 某段時間內(2018-12-01 16:50:00----2018-12-04 16:55:00)產生的二進制日誌文件內容;

stdin,stdout,stderr = ssh.exec_command('mysqlbinlog --start-date="2018-12-01 16:50:00" --stop-date="2018-12-04 16:55:00" /usr/local/mysql/data/mysql-bin.00000*')
data=stdout.read().decode('utf-8')
for i in data.split('/n'):
    print(i)

 

使用mysqlbinlog 截取 某個時間節點以前(2018-12-04 16:55:00)產生的二進制日誌文件內容;

stdin,stdout,stderr = ssh.exec_command('mysqlbinlog --stop-date="2018-12-04 16:55:00" /usr/local/mysql/data/mysql-bin.00000*')

 

 使用截取的二進制日誌文件 數據恢復

[root@localhost zhanggen]# mysql -umartin -p123.com < /tmp/first.sql 
Warning: Using a password on the command line interface can be insecure.

 

 

 

 

 

5.中繼日誌

主從架構的MySQL, 從MySQL經過遠程不斷從 主MySQL同步二進制日誌 存儲在中繼日誌,從讀取中繼日誌並執行達到主從同步的效果;

(中繼日誌 = 主服務器上的二進制日誌)

 

 

7、MySQL備份

數據庫就像企業的心臟,產生數據(血液)輸送到各個業務線處理以後迴流到心臟,循環往復,所依對它的備份、災難狀況下能夠還原相當重要;

磁盤陣列(Redundant Arrays of Independent Drives,RAID)只能在硬件層面保證1塊硬盤損壞以後數據不丟失,RAID沒法保證用戶層面的邏輯操做(本身刪個庫);

 

1.爲何要作數據備份?

災難恢復:數據丟失的狀況下快速恢復數據;(最多見場景)

需求改變:數據回滾到某1時間節點;

測試:能夠複製數據還原到測試環境,以便測試;

 

2.備份須要考慮的問題?

可容忍丟失多長時間的數據?

恢復是是否須要暫停業務?

恢復在多長時間內完成?

 

3.備份類型

3.1:根據是否須要數據庫離線的標準劃分

冷備:MySQL服務庫暫停,讀寫請求均不容許;

溫備:MySQL服務在線,備份時僅支持讀請求,不支持寫請求;

熱備:備份同時MySQL服務、讀請求、寫請求不受影響(MyISAM存儲引擎不支持熱備,innoDB存儲引擎支持)

 

3.2:根據每次備份的數據量 劃分

徹底備份(Full Backup):沒次備份整個數據量;

 

增量備份(Icreamental Backup):自上1次徹底備份、增長備份以後 增長的數據量;

PS:若是天天都作徹底備份,數據恢復的時候方便,可是備份效率低下,因此增量備份須要依賴徹底備份,是徹底備份的輔助策略;

備份策略:

Sunday徹底備份

+ Monday增量備份 + Tuesday增量備份 +Wednesday增量備份 +Thursday增量備份 +Thursday增量備份 + Thursday增量備份

 

 

恢復策略:

哈哈...若是按以上的備份策略,週六出現緊急情況,須要恢復數據,難度就比較大了,你須要拿着 Last Sunday + Monday+.....Fridy

 

差別備份(Difference Backup):

差別備份就是作1次徹底備份以後,而後天天產出的增量數據 匯聚到同一個地方備份;

差別備份比較容易恢復:由於只有2個數據集;

 

 PS:若是我周1 0點作了1次徹底備份,日後一週時間內天天0點作1次增量備份,那週六晚上18點服務器宕機了(等於週六的增量備份失敗了),那我怎麼恢復呢?

固然是二進制日誌啦!因此你在每次備份以後必定要flush logs;一下產生1個新的二進制日誌文件標記一下;

2個增量備份時間節點中間出現了岔子,才能夠利用上二進制日誌;

 

總結:

到底使用增量備份仍是差別備份根據本身的業務場景,都須要依賴徹底備份,

 其實增量備份 差別備份 只是把增量數據 放在1起存儲  仍是不放到一塊兒存的不一樣;

不管使用增量備份仍是差別備份策略都須要 用得二進制日誌;

恢復   =   徹底備份 + 增量1 +增量1 ....  + 二進制日誌

 恢復   =  徹底備份     +         差別備份   + 二進制日誌

 

3.3:根據備份的數據類型不一樣分爲

物理備份:備份數據文件

優:

備份恢復都比較簡單、快速

劣:

不能作熱備

 

邏輯備份:備份表中的數據+代碼

優:

恢復簡單

備份結果爲ASCII文件,可編輯

與存儲引擎引擎無關

能夠經過網絡備份和恢復

 

劣: 

備份和恢復都須要MySQL進程參與,不能暫停MySQL服務

備份結果佔據更多磁盤空間

浮動數丟失精度

還原以後索引須要重建

 

4.備份對象

數據:庫、表、索引

配置:MySQL配置文件、OS相關的配置文件、主從複製相關的配置

SQL代碼:存儲過程、函數、觸發器...

日誌:二進制日誌、查詢日誌、慢查詢日誌

 

5.備份工具介紹

5.1 mysqldump

MySQLdump是一款 傳統、經典的邏輯備份工具,innodb存儲引擎支持熱備、myisam存儲引擎支持溫備,備份和恢復較慢;

 

備份整個MySQL服務(全部數據庫)

[root@localhost /]# mysqldump -umartin -p123.com --master-data=2 -a --lock-all-tables > /tmp/all_database.sql
ps: -a 參備份因此數據庫

 

部分數據庫

[root@svnnew ~]# mysqldump -uwebproject -pweb --master-data=2 --databases web mysql --lock-all-tables > /tmp/web_and_mysl.sql
#記錄二進制日誌位置 #備份的全部數 #施加讀鎖
ps:--single-transaction 參數能夠實現innodb的熱備,不須要
--lock-all-tables
[root@localhost /]# less /tmp/mysql.sql 

部分表

表中的某些行

存儲過程

存儲函數

觸發器

自動記錄二進制文件以及相應positon

 

-e,  --events:   同時備份事件調度器代碼
-r,  --routines: 同時備份存儲過程和存儲函數
-d,  --no-data: 只備份表結構不備份數據
--opt

 

 

 

 

5.2 mysqldumper

mysqldum的增強版,多線程備份工具; 

 

5.3 select 表備份功能

邏輯備份工具,一般用於備份單表;

select into outfile

select * from cmdb_userinfo where id >7 into outfile '/tmp/lg7_users';    #注意mysql用戶一點要對備份的目錄有寫入權限

load data infile 

mysql> load data infile '/tmp/lg7_users' into table cmdb_userinfo;

 

 

5.4 lvm-snapshot (LVM 快照)

一款接近熱備的備份工具,備份時須要施加讀鎖;

 

5.5 xtrabackup

xtrabackuo是ibbackup的開源版本,物理備份工具,支持innodb熱備,對於MyISAM僅支持溫備,備份速度快;

 

 

 

 

5.6 mysqlhotcopy

mysql自帶 冷備工具

 

 

6.數據備份以後恢復步驟

中止MySQL服務(若是冷備)

記錄MySQL服務的配置和文件權限

複製備份文件至數據目錄

啓動服務

裝置邏輯備份

測試數據還原完成

已徹底權限重啓MySQL了

 

8、percona-toolkit工具

percona-toolkit工具包同percona-xtrabackup同樣都是用Perl寫的工具包,percona-toolkit工具包是一組高級的管理mysql的工具包集,本地、遠程分析日誌;

能夠用它採集的數據作MySQL性能分析;

 

1.安裝

[root@db ~]# ldconfig -p | grep mysql

那就添加一下:
[root@db ~]# echo '/usr/local/mysql/lib' > /etc/ld.so.conf.d/mysql.conf
[root@db ~]# ldconfig
[root@db ~]# ldconfig -p | grep mysql
出現install_driver(mysql) failed: Attempt to reload DBD/mysql.pm aborted報錯

 

2.使用 

分析日誌併產生報告

pt-query-digest mysql-bin.00000*

 

分析最近12小時以內的二進制日誌 

 

 

 

mysql配置和status進行彙總

pt-mysql-summary  --user=webproject --password='xxxxxx1234'  --port=3306  --host=172.17.10.112

 

 分析參數,並提出建議

pt-variable-advisor --user=webproject --password=xxxxxx1234  172.17.10.112

 

查找和顯示指定的Master 有多少個Slave

pt-slave-find --user=webproject --password=xxxxxx1234  --port=3306  --host=172.17.10.112

 

查詢重複索引

 pt-duplicate-key-checker  --user=webproject --password='xxxxxx1234'  --port=3306  --host=172.17.10.112

 

性能相關

 

把查詢結果輸出到數據庫

 pt-query-digest --user='martin' --password='123.com' --review  h=127.0.0.1,D=test,t=query_review--create-review-table mysql-bin.00000*

 

 

9、python操做Oracle

import cx_Oracle
orcle_db = cx_Oracle.connect('sys','oracle123','10.102.6.38:1521/historydb',cx_Oracle.SYSDBA)
cursor = orcle_db.cursor()
cursor.execute('select sysdate from dual')
data=cursor.fetchall()
print(data)
cx_Oracle API

雖然Oracle提供了pythonAPI可是,必需要求API的版本和數據庫的版本一致。

import paramiko,time
ssh = paramiko.SSHClient()
ssh._policy = paramiko.AutoAddPolicy()
ssh.connect(hostname='10.102.6.38',port=22, username='oracle',password='oracle')
# ssh.connect(hostname='10.102.6.38',port=22, username='root',password='EC_history&LINGzhi')
# ssh.exec_command('source /home/oracle/.bash_profile')
sql="echo 'show parameter;'| /u01/app/oracle/product/11.2.0/dbhome_1/bin/sqlplus sys/oracle123 as sysdba"
# ssh.exec_command('export ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1')

sql1="echo 'select sysdate from dual;'| /u01/app/oracle/product/11.2.0/dbhome_1/bin/sqlplus scott/tiger@172.16.22.25/pimdb"
#
# ssh.exec_command('export ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1')
stdin,stdout,stderr=ssh.exec_command('. ./.bash_profile;%s'%(sql))

data=stdout.read().decode('utf-8').split('\n')[11:-3]
for row in data:
    print(row)
經過paramiko自定義Oracle API
#操做 Oracle、MySQL、Redis的shell和API
class DB_API(object):
    def __init__(self,db_obj):
        self.host = db_obj.db.host
        self.user = db_obj.db_user.username
        self.pwd = db_obj.db_user.password
        self.port = db_obj.db.port
        self.type = db_obj.db.get_database_type_display()
        self.sid=db_obj.db_user.sid

    def call_api(self,sql):
        print('輸入%s的sql語句,返回執行結果,redis返回鏈接對象...'% (self.type))
        self.sql=sql
        db_engin = getattr(self,self.type)
        return db_engin()

    def Redis(self):
        conn_pool = redis.ConnectionPool(host=self.host, port=self.port, db=2, password=self.pwd)
        conn = redis.Redis(connection_pool=conn_pool)
        return conn

    def MySQL(self):
        db = pymysql.connect(self.host, self.user, self.pwd, 'mysql')
        cursor = db.cursor()
        cursor.execute(self.sql)
        data = cursor.fetchall()
        return data

    def Oracle(self):
        import cx_Oracle
        #orcle_db = cx_Oracle.connect('sys','oracle123','10.102.6.38:1521/historydb',cx_Oracle.SYSDBA)
        orcle_db = cx_Oracle.connect(self.user,self.pwd ,self.host+':'+self.port+'/'+self.sid,cx_Oracle.SYSDBA)
        cursor = orcle_db.cursor()
        cursor.execute(self.sql)
        data=cursor.fetchall()
        return data

    def generate_shell_cmd(self,sql):
        shell_cmd_dict = {
            'Redis': "echo '{sql}'| redis-cli -h {host} -p {port} -a {pwd}{user}",
            'MySQL': 'mysql -h{host} -u{user} -p{pwd} -Dmysql -e"{sql}"',
            'Oracle': [
                        ". ./.bash_profile; echo -e 'set pagesize 0\n {sql}'| /u01/app/oracle/product/11.2.0/dbhome_1/bin/sqlplus -S {user}/{pwd}@{host}/" +self.sid+" as sysdba",
                         ". ./.bash_profile; echo -e 'set pagesize 0\n {sql}'| /u01/app/oracle/product/11.2.0/dbhome_1/bin/sqlplus -S {user}/{pwd}@{host}/" + self.sid,
                       ]
        }
        if self.type=='Oracle' and self.user=='sys':
            shell_cmd =shell_cmd_dict.get(self.type)[0].format(user=self.user,pwd=self.pwd, sql=sql, host=self.host, port=self.port)
        elif self.type=='Oracle' and self.user!='sys':
            shell_cmd = shell_cmd_dict.get(self.type)[1].format(user=self.user, pwd=self.pwd, sql=sql, host=self.host, port=self.port)
        else:
            shell_cmd = shell_cmd_dict.get(self.type).format(user=self.user,pwd=self.pwd,sql=sql,host=self.host, port=self.port)
        print(shell_cmd)
        return shell_cmd

    def call_shell(self,sql):
        cmd_str = self.generate_shell_cmd(sql)
        if sys.platform == 'linux' and self.type != 'Oracle':
            task_obj = subprocess.Popen(cmd_str, stdout=subprocess.PIPE, shell=True, stderr=subprocess.PIPE)
            ret = task_obj.stdout.read().decode('utf-8') or task_obj.stderr.read().decode('utf-8')
            return ret
        else:
            ssh = paramiko.SSHClient()
            ssh._policy = paramiko.AutoAddPolicy()
            if self.type == 'Oracle':
                ssh.connect(hostname='10.102.6.38', port=22, username='oracle', password='oracle')
            else:
                ssh.connect(hostname='172.17.10.112', port=22, username='root', password='xxxxxx1234')
            stdin, stdout, stderr = ssh.exec_command(cmd_str)
            ret = stdout.read().decode('utf-8') or stderr.read().decode('utf-8')
            return ret

    def get_info(self):
        data = '獲取失敗!!'
        if self.type == 'Oracle':
            data = self.call_shell('show parameter;')
        elif self.type == 'MySQL':
            data = self.call_shell('show variables;')
        elif self.type== 'Redis':
            data = self.call_shell('info')
        return data
操做 Oracle、MySQL、Redis的shell的統一API

 

我想作  1個 能夠統一調用全部DB的API, 之前的思路是 在1臺服務器 上經過paramiko 執行 mysql -h、 sqlplus -S、redis-cli -h.....鏈接客戶端鏈接上DB執行SQL,其實這不是最佳方案,由於SQL執行後 還要對返回結果作數據處理;

from sqlalchemy import create_engine

mysql_con=create_engine('mysql+pymysql://webproject:xxxxxx1234@172.17.10.112:3306/web')
oracle_conn=create_engine('oracle+cx_oracle://scott:tiger@172.16.22.16:1521/ecdb')

for i in mysql_con.execute('show databases'):
    print(i)

for i in oracle_conn.execute('select * from v$version'):
    print(i)
sqlalchemy 版

 

 

 https://www.cnblogs.com/mengfanrong/p/5367748.html

 

 

 

 

 

 

參考博客:http://blog.51cto.com/mageedu/1062628

相關文章
相關標籤/搜索