Linux雲計算運維-MySQL

0、建初心

優秀DBA的素質前端

1、人品,不作某些事情
2、嚴謹,運行命令前深思熟慮,三思然後行,即便是依據select
3、細心,嚴格按照步驟一步一步執行,減小出錯
4、心態,遇到災難,首先要穩住,不慌張,不要受到旁人的影響
5、熟悉操做系統,Linux系統的工具和命令
6、熟悉業務(開發),編程語言
7、熟悉行業
8、喜歡數據庫
node

什麼是數據?mysql

數據是指對客觀事件進行記錄並能夠鑑別的符號,是對客觀事物的性質、狀態以及相互關係等進行記載的物理符號或這些物理符號的組合。它是可識別的、抽象的符號。
什麼是數據庫管理系統?
linux

將大量的數據規範的管理在一塊兒的軟件ios

數據庫管理系統種類c++

關係型和非關係型git

• 關係型數據庫的特色
  – 二維表
  – 典型產品 Oracle傳統企業, MySQL是互聯網企業
  – 數據存取是經過SQL
  – 最大特色,數據安全性方面強(ACID)
• NoSQL:非關係型數據庫(Not only SQL)
  – 不是否認關係型數據庫,作關係型數據庫的的補充。
  – 想作老大,先學會作老二。

RDBMS與NoSQL對比
• web1.0時代
  企業提供內容,用戶瀏覽,因此關係型數據庫夠用,併發並不高,因此不須要NoSQL。
• web2.0時代
  核心是企業提供平臺,用戶參與提供內容。這時關係型數據庫沒法知足需求了。
• 2003 NoSQL出現
  memcached誕生,關注的點是性能,而安全性關注比較低。隨着安全性需求不斷提高,因此有了redis。
• redis特色
  – 依然高性能該併發,
  – 數據持久化的功能
  – 支持多數據類型,主從複製和集羣
  – 管理再也不使用SQL了
• NoSQL特性總覽
  – 不是否認關係型數據庫,而是做爲補充,如今也有部分替代的趨勢。
  – 關注高性能,高併發,靈活性,忽略和上述無關的功能。
  – 如今也在提高安全性和使用功能。
  – 典型產品: Redis(持久化緩存,兩個半天)、 MongoDB(最接近關係型數據的NoSQL)、 Memcached。
  – 管理不適用SQL管理,而是用一些特殊的 API 或 數據接口。
  • NoSQL的分類、特色、典型產品
  – 鍵值(KV)存儲: Memcached、 Redis
  – 列存儲(column-oriented): HBASE(新浪, 360)、 Cassandra(200臺服務器集羣)
  – 文檔數據庫(document-oriented): MongoDB(最接近關係型數據庫的NoSQL)
  – 圖形存儲(Graph): Neo4j
常見數據庫企業及其產品
Oracle數據庫版本介紹
  – 7--8i--9i--10g11g--12c--18c(?)
Oracle的市場應用
  – 市場份額第一,趨勢遞減
  – 市場空間,傳統企業
  – 傳統企業也在互聯網化
MySQL數據庫版本介紹
  – 5.0--5.1--5.5--5.6--5.7--8.0
  5.0和5.1已經不能用了,5.6和5.7是如今的主流,8.0暫時尚未穩定的版本
MySQL的市場應用
  – 中、大型互聯網公司
  – 市場空間:互聯網領域第一
  – 趨勢明顯
同源產品: MariaDBperconaDB

其餘公司產品介紹
微軟: SQL Server
  – 微軟和sysbase合做開發的產品,後來本身開發,windows平臺
  – 3,4線小公司,傳統行業在用
IBM DB2
  – 市場佔有量小
  – 目前只有:國有銀行(人行、中國銀行、工商銀行等)、中國移動應用。
PostgreSQL
MongoDB
Redis
後三者普遍應用在大型互聯網公司。

MySQL發展史
1979年,報表工具Unireg出現。
1985 年,以瑞典David Axmark 爲首,成立了一家公司(AB前身), IASM引擎出現。
1990年,提供SQL支持。
1999-2000年, MySQL AB公司成立,並公佈源碼,開源化。
20004BDB引擎出現,支持事務。
2008116MySQLSun公司收購。
20090420Oracle收購Sun公司, MySQL 轉入Oracle 門下。

https://db-engines.com/en/ranking 點擊查看各類數據度廣度排名程序員

一、MySQL的安裝和配置

1、MySQL5.6.36安裝前準備

(1)克隆一個模板機器(使用centos6),克隆完作快照
(2)IP 10.0.0.52 主機名db02
(3)iptables   selinux  關閉
(4)下載好5.6.36
官網下載 ftp://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.6/ 下載完成最比如對一下md5
5)安裝依賴包 yum install -y ncurses-devel libaio-devel (6)安裝cmake yum install cmake –y (7)建立用戶 useradd -s /sbin/nologin -M mysql id mysql 2、MySQL下載安裝 (0)建立軟件下載目錄: mkdir -p /server/tools cd /server/tools/1)下載並上傳到/server/tools
將下載的MySQL上傳到服務器文件
社區版MySQL Community Server 5.6 5.6.3x 5.6.34 5.6.36 5.6.38 發佈超過6-12餘額的版本 5.7 5.7.17之後 (2)解壓: cd /server/tools tar xf mysql-5.6.36.tar.gz (3)安裝:注意修改本身下載的版本號,我這裏是5.6.36,版本號輸入錯誤會致使安裝失敗 cd mysql-5.6.36 cmake . -DCMAKE_INSTALL_PREFIX=/application/mysql-5.6.36 \ -DMYSQL_DATADIR=/application/mysql-5.6.36/data \ -DMYSQL_UNIX_ADDR=/application/mysql-5.6.36/tmp/mysql.sock \ -DDEFAULT_CHARSET=utf8 \ -DDEFAULT_COLLATION=utf8_general_ci \ -DWITH_EXTRA_CHARSETS=all \ -DWITH_INNOBASE_STORAGE_ENGINE=1 \ -DWITH_FEDERATED_STORAGE_ENGINE=1 \ -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \ -DWITHOUT_EXAMPLE_STORAGE_ENGINE=1 \ -DWITH_ZLIB=bundled \ -DWITH_SSL=bundled \ -DENABLED_LOCAL_INFILE=1 \ -DWITH_EMBEDDED_SERVER=1 \ -DENABLE_DOWNLOADS=1 \ -DWITH_DEBUG=0
執行到這裏也許會抱一個錯誤,致使安裝失敗
CMake Error: your CXX compiler: "CMAKE_CXX_COMPILER-NOTFOUND" was not found.   Pleaet CMAKE_CXX_COMPILER to a valid compiler path or name.
這是由於系統缺乏C++編譯器
yum install gcc-c++ -y

 

make && make install

太慢了...
3、配置並啓動 (1)製做軟鏈接: ln -s /application/mysql-5.6.36/ /application/mysql (2)拷貝配置文件到/etc:覆蓋原文件 cp support-files/my*.cnf /etc/my.cnf (3)初始化數據庫:建立元數據,系統數據庫 /application/mysql/scripts/mysql_install_db --basedir=/application/mysql/ --datadir=/application/mysql/data --user=mysql (4)建立關鍵目錄並設置權限: mkdir -p /application/mysql/tmp chown -R mysql.mysql /application/mysql/5)複製啓動腳本到/etc/init.d/mysqld cp support-files/mysql.server /etc/init.d/mysqld (6)啓動數據庫
chkconfig mysqld on
/etc/init.d/mysqld start netstat -lntup|grep 3307)配置環境變量 echo 'PATH=/application/mysql/bin/:$PATH' >>/etc/profile tail -1 /etc/profile source /etc/profile echo $PATH mysql select user,host,password from mysql.user;

排錯:
1、輸出
2、錯誤日誌
tail -100 /application/mysql/data/db02.err
設置密碼:
mysqladmin -u root password 'pizza123'
mysql -uroot -pizza123
清理用戶及無用數據庫(基本優化)
select user,host from mysql.user;
drop user ''@'db02';
drop user ''@'localhost';
drop user 'root'@'db02';
drop user 'root'@'::1';
select user,host from mysql.user;
drop database test;
show databases;

 

做業github

1、請列舉你瞭解到的數據庫典型產品

2、請說明企業中選擇數據庫版本的規則

3、請簡述MySQL數據庫支持的安裝方式

4、編譯安裝本身的一套MySQL數據庫

5、簡述mysql_install_db命令的經常使用參數

6、簡述5.7版本安裝過程當中與5.6的區別(本身擴展學習)

 

二、MySQL 體系結構

客戶端與服務器端模型

一、cs之間經過TCP/IP連接

二、cs之間經過socket連接

因此,對應兩種連接到數據庫的方法

• 經過網絡鏈接串web

mysql -uroot -poldboy123 -h 10.0.0.200

• 經過套接字文件

mysql -uroot -poldboy123 -S /tmp/mysql.sock


• 思考: mysql - uroot - poldboy123 使用的是什麼方式登陸的?

MySQL體系結構-實例、鏈接層、SQL層詳解

• MySQL在啓動過程
  – 啓動後臺守護進程,並生成工做線程 
  – 預分配內存結構供MySQL處理數據使用 • 實例是什麼?
  MySQL的後臺進程
+線程+預分配的內存結構。

 

 

mysqld服務器程序的構成

show processlist;能夠查看連接到MySQL的信息

SQL處理流程

在SQL層中,語句交給解析器,轉換成執行計劃,交給查詢執行

當有多種執行計劃時,交給優化器,確認執行計劃,交給查詢執行

獲得的結果(獲取數據的方式,即位置)交給存儲引擎層,

1、接收到鏈接層送過過來的「SQL」
2、由專門的模塊,會判斷SQL語法、語義(SQL語句的類型:DDL、DCL、DML)
3、將不一樣類型的語句,送到專門的處理接口(解析器)
4、解析器,將SQL解析成執行計劃
5、優化器,會選擇「它」最優的執行計劃交給執行器
6、執行器,執行 執行計劃,得出如何去「磁盤」獲取數據的方法
7、專門線程將獲取數據的方法,送給下層(存儲引擎層)繼續處理。
8、驗證受權,當前用戶對 庫或表對象有沒有操做的權限。
9、查詢高速緩存query_cache。
10、記錄修改操做日誌binlog。

 

 

存儲引擎層

真正接觸數據,和數據打交道的,接受SQL層執行計劃的結果,去指定的位置取指定的數據,或者將數據存儲在哪一個位置

存儲引擎是充當不一樣表類型的處理程序的服務器組件。 
• 存儲引擎用於:
  – 存儲數據
  – 檢索數據
  – 經過索引查找數據
• 雙層處理
  – 上層包括SQL解析器和優化器
  – 下層包含一組存儲引擎
• SQL 層不依賴於存儲引擎:
  – 引擎不影響SQL處理
  – 有一些例外,
依賴於存儲引擎的功能
• 存儲介質
• 事務功能
• 鎖定
• 備份和恢復
• 優化
• 特殊功能:
  – 全文搜索
  – 引用完整性
  – 空間數據處理

 

簡述MySQL的整個處理過程

首先,在磁盤中存儲的數據確定不是這個表的形式,在命令運行以後,通過一系列的操做,表格才展示在咱們眼前
一、鏈接層
  通訊協議---驗證---受權---提供連接線程---接收SQL語句,並交給SQL層
二、SQL層
  見上面的流程,驗證語法、語義(查詢or插入)---query_cache---解析---優化---
三、存儲引擎層
  去指定位置取指定的數據---返回給SQL層---處理---鏈接層交給用戶展示

數據庫的邏輯結構

列、數據行、表、庫 就是這些抽象出來的結構

在物理層,是怎麼存儲到磁盤的呢?見下圖,MySQL對磁盤的使用

注:咱們只研究到文件系統層

程序文件隨數據目錄一塊兒存儲在服務器安裝目錄下。執行各類客戶機程序、管理程序 和實用程序時將建立程序可執行文件和日誌文件。
首要使用磁盤空間的是數據目錄。
• 服務器日誌文件和狀態文件: 包含有關服務器處理的語句的信息。日誌可用於進行故障排除、監視、複製和恢復。
• InnoDB 日誌文件: (適用於全部數據庫)駐留在數據目錄級別。
• InnoDB 系統表空間:
  包含數據字典、撤消日誌和緩衝區。
  每一個數據庫在數據目錄下均具備單一目錄(不管在數據庫中建立何種類型的表)。
數據庫目錄存儲如下內容:
  - 數據文件: 特定於存儲引擎的數據文件。這些文件也可能包含元數據或索引信息,具體取決於所使用的存儲引擎。
  - 格式文件 (.frm): 包含每一個表和/或視圖結構的說明,位於相應的數據庫目錄中。
  - 觸發器: 與某個表關聯並在該表發生特定事件時激活的命名數據庫對象。
數據目錄的位置取決於配置、操做系統、安裝包和分發。
典型位置是 /var/lib/mysql。 MySQL在磁盤上存儲系統數據庫 (mysql)。
mysql 包含諸如用戶、特權、插件、 幫助列表、事件、時區實現和存儲例程之類的信息。

頁(默認是16k):是mysql數據庫存儲的最小單元
區:連續的多個頁組成,是一系列練習的數據行
段:一個表(分區表)就是一個段,包含了多個區

三、MySQL的基本管理

• MySQL的鏈接管理

mysql命令

-u   用戶名
-p   密碼

例子: 
mysql -uroot -pizza123

-h ip  
例子:
mysql -uroot -pizza123 -h 10.0.0.52

-P 3308
例子:
mysql -uroot -pizza123 -h 10.0.0.52 -P 3308

-S /tmp/mysql.sock  套接字目錄
例子:
mysql -uroot -pizza123 -S /application/mysql/tmp/mysql.sock

-e "show variables like 'server_id';"  免交互式執行SQL命令,直接得到結果
例子:
mysql -uroot -pizza123  -e "show variables like 'server_id';"

mysqladmin 
mysqladmin -uroot -p password pizza123

• MySQL用戶管理及權限基本管理

用戶權限由用戶名+主機範圍構成

對比一下Linux用戶和MySQL用戶

user:表示使用哪一個用戶登錄

host:表示從哪些地址訪問這個數據庫

• 用戶的做用: 
  – 1、用戶登陸
  – 2、用於管理數據庫及數據
• 權限: 針對不一樣用戶設置不一樣對象管理能力
  – 對數據庫的讀、寫等操做
  – (insert update、select等)
• 角色:
  – 數據庫定義好的一組權限的定義
  – (all privileges、replication slave等)
• 權限範圍:
  – 全庫級別: *.*
  – 單庫級別:oldboy.*
  – 單表級別:oldboy.t1

 

超級管理(管理)用戶:root ,當前若是要進行受權操做只能用root進行

也不用再去建立了,固然也能夠根據不一樣的地址,主機域去設置不一樣的密碼和操做

mysqladmin  -uroot -p password  pizza123  這條命令,執行的是root@localhost,即只在本地生效的權限範圍

普通用戶(開發)的權限包括:select update delete insert drop  ...用的比較多的

用戶操做命令

• 查看當前用戶: 
  select user,host from mysql.user;
• 建立用戶
  CREATE USER '用戶'@'主機' IDENTIFIED BY '密碼';
  create user 'pizza'@'localhost' identified by 'pizza123'; 
#只有鏈接權限 企業裏建立用戶通常是受權一個內網網段登陸,最多見的網段寫法有兩種。
  方法1:172.16.1.%(%爲通配符,匹配全部內容)。
  方法2:172.16.1.0/255.255.255.0,可是不能使用172.16.1.0/24,是個小遺憾。
# 遠程登陸,帶參數-h
  mysql> create user web01@'10.0.0.%' identified by '123';
  [root@web01 mysql-5.6.43]# mysql -uweb01 -p123 -h10.0.0.7
  登錄後的普通用戶,權限很低

標準的建用戶方法:
  create user 'web'@'172.16.1.%' identified by 'web123';
• 查看用戶對應的權限
  show grants for oldboy@localhost\G
• 刪除用戶
  drop user
'user'@'主機域' 或者 drop user root@'127.0.0.1';
  用戶優化:只保留 有密碼和有用戶名的
  | root | 127.0.0.1 |
  | root | localhost |
  特殊的刪除方法:
  mysql> delete from mysql.user where user='pizza' and host='localhost';
  Query OK, 1 row affected (0.00 sec) mysql> flush privileges;

• 給用戶受權
  create user 'pizza'@'localhost' identified by 'pizza123';  
  select user,host from mysql.user;
  GRANT ALL ON *.* TO 'pizza'@'localhost';
  SHOW GRANTS FOR 'pizza'@'localhost'\G
• 建立用戶的同時受權
  grant all on *.* to pizza@'172.16.1.%' identified by 'pizzal123';
  flush privileges; #<==能夠不用。
  create user 'pizza'@'localhost' identified by 'pizza123';
  GRANT ALL ON *.* TO 'pizza'@'localhost';
• 受權和root同樣的權限
  grant all on *.* to system@'localhost' identified by 'pizzal123' with grant option; • 收回權限
  REVOKE INSERT ON
*.* FROM pizza@localhost;
• 能夠受權的用戶權限
  INSERT,SELECT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE,
  REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES,
  LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW,
  SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER,
  CREATE TABLESPACE
• 開發用戶 擁有的基本權限
  INSERT,SELECT, UPDATE, DELETE, CREATE, DROP
  grant INSERT,SELECT, UPDATE, DELETE, CREATE, DROP on testdb.* to web01@‘10.0.0.%’;
• 工做博客受權:
  grant select,insert,update,delete,create,drop on blog.* to 'blog'@'172.16.1.%' identified by 'blog123';
  revoke create,drop on blog.* from 'blog'@'172.16.1.%';
最多:select,insert,update,delete • 注意: 思考一下若是在oldboy.*,設置了select,insert,update,delete 在oldboy.t1設置了select,
  那麼用戶在t1表的最終權限應該是什麼。 回收權限的時候又該怎麼作?
實驗後的結論:
  若是對於某個用戶在不一樣數據庫級別都設置了權限,最終權限相疊加,以加起來的最大權限爲準。
建議:不要多範圍受權

 

 

• MySQL的啓動和關閉(啓動腳本介紹)

 數據庫的啓動流程介紹

mysql最終啓動的是mysqld進程,經過他提供的啓動腳本,不能直接啓動mysqld

數據庫的關閉

• mysqladmin shutdown 
• servive mysqld stop
kill -9 ? 慎用
• 第三種爲利用系統進程管理命令關閉MySQL。
  – kill pid #<==這裏的pid爲數據庫服務對應的進程號。
  – killall mysqld #<==這裏的mysqld是數據庫服務對應的進程名字。
  – pkill mysqld #<==這裏的mysqld是數據庫服務對應的進程名字。 可經過以下地址查看生產高併發環境野蠻粗魯殺死數據庫致使故障企業案例:
  http:
//oldboy.blog.51cto.com/2561410/1431161
  http://oldboy.blog.51cto.com/2561410/1431172

 

MySQL啓動報錯

停數據庫----去mysql/data目錄下--隨便改一個文件(目錄下的一個文件權限改爲root)---啓動數據庫

報錯

 

常規的報錯代碼整理 http://oldboy.blog.51cto.com/2561410/1728380

• MySQL數據庫配置文件詳解

啓動以前都作了什麼?

一、程序在哪

二、啓動後去哪裏找數據

三、啓動以後分配多大內存

...

n、還有許許多多的問題

MySQL的初始化配置文件

預編譯配置項,即在使用cmake時,硬編碼設置的參數,指定了如安裝目錄、數據目錄、sock目錄

命令行設置,在命令行上配置參數

/application/mysql/bin/mysqld_safe 用來啓動mysql,由於設置過環境變量,能夠直接運行

mysqld_safe   --socket=/tmp/mysql.sock  --port=3307 &

連接,不能用老的方式了

mysql  -uroot  -ppizza -S  /tmp/mysql.sock

初始化配置文件,/etc/my.cof

標籤的種類和影響的程序

選項文件示例

[mysqld]
basedir=/application/mysql
datadir=/application/mysql/data
socket=/application/mysql/tmp/mysql.sock
port=3306
server_id=10
log-error=/var/log/mysql.log
log-bin=/application/mysql/data/mysql-bin
binlog_format=row
skip_name_resolve

[mysql]
socket=/application/mysql/tmp/mysql.sock


 

  1. 數據庫的啓動(客戶端)
    1. 啓動文件的啓動選項包括
      1. 共享內存  
      2. 日誌記錄
      3. 系統變量
      4. 默認存儲引擎
      5. 命名管道連接
  2. 數據庫的連接(服務器)

優先級

mysql 啓動參數設置
1、預編譯時候設置參數,參數會硬編碼到程序中
2、命令行方式設定啓動參數
3、初始化的配置文件
2>3>1

 

MySQL爲咱們配置了不少配置文件,配置文件讀取順序以下

自定義配置文件位置,系統本身是找不到的

vim /tmp/aa.txt    
[mysqld]
basedir=/application/mysql
datadir=/application/mysql/data
port=3307
socket=/tmp/mysql.sock

 

使用自定義的配置文件
/etc/init.d/mysqld stop
mysqld_safe --defaults-file=/tmp/aa.txt &

• 多實例簡介及配置

 一個MySQL實例就是一個進程,多個線程,必定量預分配的內存空間

多實例就是,多個這樣的實例管理不一樣的數據,和一些日誌

思路

1、啓動多個mysqld進程
2、規劃多套數據
3、規劃多個端口
4、規劃多套日誌路徑

 

多實例配置

1、建立多套目錄

mkdir -p /data/330{7,8,9}

2、準備多套配置文件

vim /data/3307/my.cnf
[mysqld]
basedir=/application/mysql
datadir=/data/3307
server-id=3307
port=3307
log-bin=/data/3307/mysql-bin
socket=/data/3307/mysql.sock
log-error=/data/3307/mysql.log

vim /data/3308/my.cnf
[mysqld]
basedir=/application/mysql
datadir=/data/3308
server-id=3308
port=3308
log-bin=/data/3308/mysql-bin
socket=/data/3308/mysql.sock
log-error=/data/3308/mysql.log

vim /data/3309/my.cnf
[mysqld]
basedir=/application/mysql
datadir=/data/3309
server-id=3309
port=3309
log-bin=/data/3309/mysql-bin
socket=/data/3309/mysql.sock
log-error=/data/3309/mysql.log


3、初始化多套數據

/application/mysql/scripts/mysql_install_db --basedir=/application/mysql/ --datadir=/data/3307 --user=mysql
/application/mysql/scripts/mysql_install_db --basedir=/application/mysql/ --datadir=/data/3308 --user=mysql
/application/mysql/scripts/mysql_install_db --basedir=/application/mysql/ --datadir=/data/3309 --user=mysql


4、啓動多個實例

mysqld_safe --defaults-file=/data/3307/my.cnf &
mysqld_safe --defaults-file=/data/3308/my.cnf &
mysqld_safe --defaults-file=/data/3309/my.cnf &

5、查看啓動端口
netstat -lnp |grep 330


6、分別鏈接測試

mysql -S /data/3307/mysql.sock -e "show variables like 'server_id';"
mysql -S /data/3308/mysql.sock -e "show variables like 'server_id';"
mysql -S /data/3309/mysql.sock -e "show variables like 'server_id';"

 

做業

1、列出MySQL在Linux下的兩種鏈接方式

2、簡述mysql修改密碼方法

3、簡述實例的構成

4、結合MySQL體系結構,說明一條SQL語句的執行過程

5、mysql的默認日誌文件在什麼位置

6、簡述MySQL的啓動方式

7、簡述MySQL配置文件讀取順序

8、配置MySQL多實例,端口分別爲3307 3308 3309

9、請介紹mysql鏈接命令的經常使用參數,並說明功能

10、請簡述MySQL的邏輯構成

 

• 數據庫對象管理——SQL(庫、表、行記錄)

 

四、MySQL客戶端工具及SQL入門

• MySQL 客戶端命令

mysql命令

• mysql: 
  – 用於數據庫鏈接管理
    – 前面章節已經使用過(略。)
    – 命令接口自帶命令
      • 一、\h 或 help 或 ?
      • 二、\G 鍵值對的方式排列
      • 三、\T 或 tee 記錄到日誌
      • 四、\c 或 CTRL+c 結束上一條命令
      • 五、\s 或 status 查看數據庫基本狀態信息
      • 六、\. 或 source 調用外部SQL腳本
      • 七、\u 或use

  – 將 用戶SQL 語句發送到服務器,管理數據庫
    結構化查詢語言,MySQL接口程序只負責接受SQL,傳送給SQL層
    – DDL:數據庫(對象)定義語言
    – DCL:數據控制語言(grant、revoke)
    – DML:數據(行)操做語言(update、delete、insert)
    - DQL:數據查詢語言(show、select)
• mysqladmin:
  – 命令行管理工具
• mysqldump:
  – 備份數據庫和表的內容

source命令使用

• 在 mysql 中處理輸入文件: 
• 若是這些文件包含 SQL 語句,則稱爲:
  – 「腳本文件」
  – 「批處理文件」
• 使用 SOURCE 命令:
  mysql> SOURCE /data/mysql/world.sql
  或者使用非交互式:
  mysql</data/mysql/world.sql

 

mysqladmin命令

• DBA的命令行客戶端工具 
• 多項功能:
  – 「強制迴應 (Ping)」服務器。
  – 關閉服務器。
  – 建立和刪除數據庫。
  – 顯示服務器和版本信息。
  – 顯示或重置服務器狀態變量。
  – 設置口令
  – 從新刷新受權表。
  – 刷新日誌文件和高速緩存
  – 啓動和中止複製
  – 顯示客戶機信息 • 命令幫助及基本語法:
  mysqladmin
--help
  mysqladmin -u<name> -p<password> commands • 例子:
  mysqladmin version
  mysqladmin status
  mysqladmin
ping
  mysqladmin processlist
  mysqladmin shutdown
  mysqladmin variables
  …

 

mysqldump命令簡介

• 數據庫備份工具。 
• 命令幫助及基本語法:
mysqldump –help
Usage: mysqldump [OPTIONS] database [tables]
OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
OR mysqldump [OPTIONS] --all-databases [OPTIONS]

 

數據庫對象:庫、表

庫的名字,庫的基本屬性 create  database blog;

• MySQL 獲取幫助的方法

help命令的使用

• 查看完整的 SQL 類別列表: 
mysql> HELP CONTENTS
...
Account Management
Administration
Compound Statements
Data Definition
Data Manipulation Data Types
...
• 有關特定 SQL 類別或語句的幫助:
mysql> HELP Data Manipulation
mysql> HELP JOIN
• 有關與狀態相關的 SQL 語句的幫助:
mysql> HELP STATUS

 

• DDL操做簡介

DDL操做:
    對象:
        庫:
        定義什麼?
        1、庫名字
        2、庫的基本屬性
        如何定義?
        create database lufei;
        create schema  lf;
        show databases;
        create database llf CHARACTER SET utf8 ;
        show create database llf;
        drop database llf;
        help  create database;
        字符集:  CHARACTER SET [=] charset_name
        排序規則:COLLATE [=] collation_name
        
        改庫的字符集:
        ALTER DATABASE [db_name] CHARACTER SET  charset_name COLLATE collation_name
        mysql> alter database lf charset utf8mb4;
        mysql> show create database lf;
    
        表:
            表數據:數據行
            表屬性(元數據):表名、列名字、列定義(數據類型、約束、特殊列屬性)、表的索引信息
        定義什麼?
        定義表的屬性。
        use  lufei;
        建立:
        create table t1 (id int ,name varchar(20));
        查詢:
        show tables;
        show create table t1;
        desc 
        刪除
        drop table t1;
        修改:
        (1)在表中添加一列
        alter table t1 add age int;
        (2)添加多列
        alter table t1 add bridate datetime, add gender enum('M','F');
        (3)在指定列後添加一列,沒有before(,這是一個無關緊要的選項,下降開發需求)
        alter table t1 add stu_id int after id;
        (4)在表中最前添加一列
        alter table t1 add sid int first;
        (5)刪除列
         alter table t1 drop sid;
        (6)修改列名
        alter table t1 change name stu_name varchar(20);
        (7)修改列屬性
        alter table t1 modify stu_id varchar(20);
        (8)修改表名
        rename table t1 to student;
        alter table student rename  to stu;

 

• DDL 語句之管理數據庫


• 查看數據庫
  show databases;
  show databases like '%old%'; • 獲取命令幫助
  ? contents
  ?Administration
  ? show database
• 建立數據庫
  CREATE DATABASE oldboy;  #字符集和編譯指定相同.
• 獲取命令幫助
  ? contents
  ?Data Definition
  ? create database
• 查看建庫的語句
  show create database oldboy\G
• 指定字符集建庫
  CREATE DATABASE db_name CHARACTER SET 
  charset_name COLLATE collation_name
  CREATE DATABASE oldgirl CHARACTER SET gbk COLLATE
  gbk_chinese_ci;
  show character set;#找字符集和校對規則.
• 改庫的字符集:
  ALTER DATABASE [db_name] CHARACTER SET  charset_name COLLATE collation_name
  ALTER DATABASE oldgirl CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
• 刪庫 drop database oldboy;
• 切庫 use oldboy;
• 查看當前所在的庫 select database(); select user();
• 查看庫裏的表 show tables;

 

• DDL語句之管理用戶(上面已說過)

• 用戶: 
  ‘user’@‘主機域’ 
• 幫助: 
  ? Account Management 
• 經常使用命令: 
  1.查看當前用戶 
  2.建立用戶 
  3.查看用戶對應的權限 
  4.刪除用戶 
  5.給用戶受權 
  6.收回權限 
  7.工做博客受權

 

• DDL 語句之管理表 與 案例介紹

建表、查看變結構、查看建表語句、改表名

• 表的屬性: 
  – 字段、數據類型、索引
  – 默認:字符集、引擎
• 創建表
  create table <表名> (<字段名1> <類型1> , …<字段名n> <類型n>);
• 獲取幫助
  help create table; • 查看錶結構:
  desc student;
• 查看建表語句:
  show create table student\G
• 更改表名
  rename table student to test;
  alter table test rename to student;

 

修改表結構

• 原表: 
  CREATE TABLE `test` (
    `id` int(4) NOT NULL AUTO_INCREMENT,
    `name` char(20) NOT NULL,
    PRIMARY KEY (`id`)
  ) ENGINE=InnoDB DEFAULT CHARSET=UTF8; • 先添加性別列,長度爲4,內容非空
  alter table test add sex
char(4) NOT NULL;
• 指定添加年齡列到name列後面的位置,示例以下:
  alter table test add age int(4) after name;
• 經過下面的命令在第一列添加qq字段。
  alter table test add qq varchar(15) first; • 若要刪除字段,可採用以下命令。
  alter table test drop qq;
• 若要同時添加兩個字段,可採用以下命令。
  alter table test add age tinyint(
2) first,add qq varchar(15);
• 修改字段類型的命令以下:
  alter table test modify age char(4) after name;
  Query OK, 6 rows affected (0.00 sec)
  Records: 6 Duplicates: 0 Warnings: 0
• 修改字段名稱的命令以下:
  alter table test change age oldboyage char(4) after name;

添加表字段
alter table table1 add transactor varchar(10) not Null;
alter table   table1 add id int unsigned not Null auto_increment primary key

修改某個表的字段類型及指定爲空或非空
alter table 表名稱 change 字段名稱 字段名稱 字段類型 [是否容許非空];

alter table 表名稱 modify 字段名稱 字段類型 [是否容許非空];

alter table 表名稱 modify 字段名稱 字段類型 [是否容許非空];

修改某個表的字段名稱及指定爲空或非空
alter table 表名稱 change 字段原名稱 字段新名稱 字段類型 [是否容許非空]

刪除某一字段
ALTER TABLE mytable DROP 字段 名;

添加惟一鍵
ALTER TABLE `test2` ADD UNIQUE ( `userid`)

修改主鍵

ALTER TABLE `test2` DROP PRIMARY KEY ,ADD PRIMARY KEY ( `id` )

增長索引

ALTER TABLE `test2` ADD INDEX ( `id` )

ALTER TABLE `category ` MODIFY COLUMN `id`  int(11) NOT NULL AUTO_INCREMENT FIRST ,ADD PRIMARY KEY (`id`);

第一步:給 id 增長auto_increment 屬性
alter table test modify id int(11)  auto_increment;
第二步:給自增值設置初始值
alter table test  auto_increment=0;
思考:change和modify該如何選擇?

修改主鍵的sql語句塊以下:
mailbox 表新增字段

DROP PROCEDURE IF EXISTS mailbox_column_update;
CREATE PROCEDURE mailbox_column_update() BEGIN
    -- 新增刪除標誌列
    IF NOT EXISTS(SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='cbs' AND table_name='mailbox' AND COLUMN_NAME='delete_flag') THEN
            ALTER TABLE mailbox ADD   delete_flag  int  DEFAULT 2   NOT NULL;
    END IF;
    -- 新增刪除日期列
    IF NOT EXISTS(SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='cbs' AND table_name='mailbox' AND COLUMN_NAME='delete_date') THEN
            ALTER TABLE mailbox ADD  delete_date  int  DEFAULT 0   NOT NULL;
    END IF;
    -- 若是存在字段account_mail,則修改字段長度
    IF EXISTS(SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='cbs' AND table_name='mailbox' AND COLUMN_NAME='email_account')
    THEN
        alter table mailbox modify column email_account varchar(320);
    END IF;
    -- 若是不存在主鍵列,則設置雙主鍵
    IF ((SELECT count(*) FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA ='cbs' AND table_name='mailbox' AND CONSTRAINT_NAME ='PRIMARY' AND (COLUMN_NAME ='email_account' OR COLUMN_NAME = 'company_id'))=0)THEN
                ALTER TABLE mailbox ADD primary key (company_id,email_account);
    -- 若是隻存在一個主鍵列
    ELSEIF ((SELECT count(*) FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA ='cbs' AND table_name='mailbox' AND CONSTRAINT_NAME ='PRIMARY' AND (COLUMN_NAME ='email_account' OR COLUMN_NAME = 'company_id'))<2)THEN
                ALTER TABLE mailbox  DROP PRIMARY KEY,ADD primary key (company_id,email_account);
    END IF;

 

• DML 語句之管理表中的數據

• 備份數據備用 
  mysqldump以SQL語句形式將數據導出來。
  mysqldump -B --compact oldboy >/opt/bak.sql
• insert 插入數據
  use  lufei;
   create table t1 (id int ,name varchar(20));
  # 要根據 表結構 插入
    insert into t1 values(1,'zhang3');
    select * from t1;
    insert into t1 values (2,'li4'),(3,'wang5'),(4,'ma6');
  # 向指定列 插入
    insert into t1(name) values ('xyz');
• 修改數據
  update  t1  set name='zhang33' ;   --會更新表中全部行的name字段,比較危險
  update  t1  set name='zhang55' where id=1;  
      --update在使用時通常都會有where條件去限制。
  update test set id=6 where name='kaka';
  練習:把ID爲2的名字改成bingbing.
• 防止不加條件誤刪:
  mysql -U
  update test set name='lanlan';
  ERROR 1175 (HY000): You are using safe update mode
  and you tried to update a table without a WHERE that uses a KEY column   至於防止誤操做致使上述數據庫故障案例的方法之一,
  請參見http:
//oldboy.blog.51cto.com/2561410/1321061 • 刪除(delete)
  delete from test; #邏輯刪除,一行一行刪。 刪除全部
  delete from t1   where  id=2; 刪除指定數據
  truncate table test; #物理刪除,pages(block),效率高。 DDL操做
• 案例:不刪除,而是僞刪除。添加字段state,改變字段的值實現僞刪除
  alter table test add state tinyint(2) not null default 1;
  update test set state=1;
  正常顯示:
  select * from test where id=1;
  update test set state=0 where name='oldboy';

 

• DQL

開發環境準備

- 導入world.sql
- 應用腳本
  登錄mysql
  mysql> source /server/tools/world.sql
  show databases;
    mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| world              |
+--------------------+
4 rows in set (0.00 sec)
- 建立用戶(能遠程連接的用戶),使用sqlyog(有聯想功能)登錄數據庫   - create user root@'10.0.0.%' identified '123';
  - grant all on *.* to 'root'@'10.0.0.%'

select 的基本格式

• 查詢表中的數據 
命令語法:select <字段1,字段2,...> from < 表名 > where < 表達式 > and < 表達式 >。
其中,select、from、where是不能隨便改的,是關鍵字,支持大小寫。
select <字段1,字段2,...> from < 表名 > where < 表達式 >
select user,host,password from mysql.user; select * from oldboy.test;
select
id,name from oldboy.test;
select
id,name from test where id=2;
select id,name from test where name='oldgirl';
select
id,name from test where id>2;
select id,name from test where id>2 and id<4;
select
id,name from test where id>2 or id<4;
select id,name from test;
select id,name from test order by id asc;
select id,name from test order by id desc;
select id,name from test limit 1,3;

help  select;

查詢select語法詳解

• 基本語法 
  SELECT *|{[DISTINCT] column|select_expr [alias], ...]}
    [FROM [database.]table]
    [WHERE conditions]; • WHERE條件又叫作過濾條件,它從FROM子句的中間結果中去掉全部
  條件conditions不爲TRUE(而爲FALSE或者NULL)的行
• WHERE子句跟在FROM子句後面
• 不能在WHERE子句中使用列別名 • 例1:where字句的基本使用
  SELECT
* FROM world.`city` WHERE CountryCode='CHN';
  or
  SELECT * FROM world.`city` WHERE CountryCode='chn';   注意: WHERE中出現的字符串和日期字面量必須使用引號括起來
  這裏,字符串字面量寫成大寫或小寫結果都同樣,即不區分大小寫進行查詢。
  這和ORACLE不一樣,ORACLE中WHERE條件中的字面量是區分大小寫的 • 例2:where字句中的邏輯操做符:
  SELECT
* FROM world.`city` WHERE CountryCode='chn' AND district = 'anhui';
• 邏輯操做符介紹:
  – and 邏輯與。只有當全部的子條件都爲true時,and才返回true。不然返回false或null
  – or 邏輯或。只要有一個子條件爲true,or就返回true。不然返回false或null
  – not 邏輯非。若是子條件爲true,則返回false;若是子條件爲false,則返回true
  – xor 邏輯異或。當一個子條件爲true而另外一個子條件爲false時,其結果爲true;
    當兩個條件都爲true或都爲false時,結果爲false。不然,結果爲null • 例3 :where字句中的範圍比較:
  SELECT
* FROM world.`city` WHERE population BETWEEN 100000 AND 200000 ; • 例4:where字句中的IN
  SELECT
* FROM city WHERE countrycode IN ('CHN','JPN'); • 例5:where字句中的like
  – 語法:
    like ‘匹配模式字符串’
  – 實現模式匹配查詢或者模糊查詢:
    測試一個列值是否匹配給出的模式
  – 在‘匹配模式字符串’中,能夠有兩個具備特殊含義的通配字符:
    
%:表示0個或者任意多個字符
    _:只表示一個任意字符     SELECT
* FROM city WHERE countrycode LIKE 'ch%'; • ORDER BY子句用來排序行
• 若是SELECT語句中沒有ORDER BY子句,
  那麼結果集中行的順序是 不可預料的
• 語法: SELECT
expr
  FROM table
  [WHERE condition(s)]
  [ORDER BY {column, expr, numeric_position} [Asc|DEsc]];
• 其中:
  – Asc:執行升序排序。默認值
  – DEsc:執行降序排序
  – ORDER BY子句通常在SELECT語句的最後面 • 例1: 基本使用
  SELECT
* FROM city ORDER BY population;
• 例2:多個排序條件
  SELECT * FROM city ORDER BY population,countrycode;
• 例3:以select字句列編號排序
  SELECT * FROM city ORDER BY 5;
• 例4:desc asc
  SELECT * FROM city ORDER BY 5 desc;
• 例5:NULL值的排序 在MySQL中,把NULL值當作一列值中的最小值對待。
  所以,升序排序時,它出如今最前面
LIMIT • MySQL特有的子句。
• 它是SELECT語句中的最後一個子句(在order by後面)。
• 它用來表示從結果集中選取最前面或最後面的幾行。
• 偏移量offset的最小值爲0。
• 語法: limit
<獲取的行數> [OFFSET <跳過的行數>]
  或者 limit [<跳過的行數>,] <獲取的行數>
  SELECT * FROM city ORDER BY 5 DEsc LIMIT 4; 注:先按照人口數量進行降序排序,而後使用 limit 從中挑出最前面的 4 行。 若是沒有 order by 子句,返回的 4 行就是不可預料的。
• 傳統的鏈接寫法(使用where)   SELECT NAME,ci.countrycode ,cl.language ,ci.population
  FROM city ci , countrylanguage cl WHERE ci.`CountryCode`
=cl.countrycode; 注意:一旦給表定義了別名,那麼原始的表名就不能在出如今該語句 的其它子句中了 • NATURAL JOIN子句
• 自動到兩張表中查找全部同名同類型的列拿來作鏈接列,進行相等
鏈接 SELECT NAME,countrycode ,LANGUAGE ,population
FROM city NATURAL JOIN countrylanguage WHERE population
> 1000000
ORDER BY population; 注意:在
select 子句只能出現一個鏈接列 • 使用using子句
  SELECT NAME,countrycode ,LANGUAGE ,population
  FROM city JOIN countrylanguage USING(countrycode); • UNION [DISTINCT]
• UNION ALL
• 語法:
  SELECT ...
  UNION [ALL
| DISTINCT]
  SELECT ...
  [UNION [ALL | DISTINCT]
  SELECT ...]
• UNION用於把兩個或者多個select查詢的結果集合併成一個
• 進行合併的兩個查詢,其SELECT列表必須在數量和對應列的數據類型上保持一致
• 默認會去掉兩個查詢結果集中的重複行
• 默認結果集不排序
• 最終結果集的列名來自於第一個查詢的SELECT列表 • 「Group By」從字面意義上理解就是根據「By」指定的規則對數據進行分組,
所謂的分組就是將一個「數據集」劃分紅若干個「小區域」,而後針對若干個 「小區域」進行數據處理。
• Having與Where的區別
  – where 子句的做用是在對查詢結果進行分組前,將不符合where條件的行去掉,
    即在分組以前過濾數據,where條件中不能包含聚組函數,使用where條件過濾出特定的行。
  – having 子句的做用是篩選知足條件的組,即在分組以後過濾數據,
    條件中常常包含聚 組函數,使用having 條件過濾出特定的組,也能夠使用多個分組標準進行分組。 • 子查詢定義
  – 在一個表表達中能夠調用另外一個表表達式,這個被調用的表表達式叫作子查詢( subquery),
    我麼也稱做子選擇(subselect)或內嵌選擇(inner
select)。
    子查詢 的結果傳遞給調用它的表表達式繼續處理。
  – 子查詢(inner query)先執行,而後執行主查詢(outer query)
  – 子查詢按對返回結果集的調用方法,可分爲:where型子查詢,from型子查詢及exists 型子查詢。
• 使用子查詢原則
  – 一個子查詢必須放在圓括號中。
  – 將子查詢放在比較條件的右邊以增長可讀性。
    子查詢不包含 ORDER BY 子句。對一個 SELECT 語句只能用一個 ORDER BY 子句,而且
    若是指定了它就必須放在主 SELECT 語句的最後。
  – 在子查詢中能夠使用兩種比較條件:
    單行運算符(>, =, >=, <, <>, <=) 和多行運算符 (IN, ANY, ALL)。

 

查詢select案例詳解

查詢以前,先看一下表的結構
DESC world.city SELECT
id ,NAME FROM world.city; SELECT * FROM world.`city`;
-- select 條件查詢 where
  注意: WHERE中出現的字符串和日期字面量必須使用引號括起來
  這裏,字符串字面量寫成大寫或小寫結果都同樣,即不區分大小寫進行查詢。
  這和ORACLE不一樣,ORACLE中WHERE條件中的字面量是區分大小寫的
---- 1、查詢中國(CHN)全部的城市信息 SELECT * FROM world.`city` WHERE countrycode='CHN'; ---- 2、查詢中國(CHN)安徽省全部的城市信息。 AND SELECT * FROM world.`city` WHERE countrycode='CHN' AND district='anhui'; ---- 3、查詢世界上人口數量在10w-20w城市信息 BETWEEN AND SELECT * FROM world.`city` WHERE population BETWEEN 100000 AND 200000 ; ---- 4、中國或者日本的全部城市信息 IN where字句中的IN SELECT * FROM world.city WHERE countrycode IN ('CHN','JPN'); ---- 5、模糊查詢 LIKE SELECT * FROM world.city WHERE countrycode LIKE 'ch%'; -- select 排序並限制 ORDER BY ---- 按照人口數量排序輸出中國的城市信息(ASC\DESC)   ASC 升序 DESC 降序
  order by 字句通常在select語句的後面
SELECT
* FROM world.`city` WHERE countrycode='CHN' ORDER BY population ASC; SELECT * FROM world.`city` WHERE countrycode='CHN' ORDER BY population DESC; ---- 按照多列排序人口+省排序
SELECT * FROM world.`city` WHERE countrycode='CHN'
ORDER BY Population,District DESC; 多個條件用,分割,
---出現的效果是,按照最後一個排序,但有時候也不是按照最後一個,會出現意想不到的效果
---通常排序時,最好仍是使用單列 SELECT
* FROM world.`city` WHERE countrycode='CHN' ORDER BY id DESC ; ---安裝列所在位置,排序 SELECT * FROM city ORDER BY 5 DESC ; ---就是按照第5列population --- NULL值的排序,在MySQL中,把NULL值當作一列的最小值
1-10 LIMIT SELECT * FROM world.`city` WHERE countrycode='CHN' ORDER BY 5 DESC LIMIT 20; 11-20 SELECT * FROM world.`city` WHERE countrycode='CHN' ORDER BY 5 DESC LIMIT 10,10 ; --至關於 SELECT * FROM world.`city` WHERE countrycode='CHN' ORDER BY 5 DESC LIMIT 10 OFFSET 10 ;
-- 錶鏈接查詢 DESC city DESC countrylanguage 傳統的鏈接寫法(使用where---- 中國全部城市信息+使用語言(city+countrylanguage)
--一、從city中顯示城市名 SELECT NAME ,countrycode ,population FROM city WHERE countrycode
='CHN'
--二、從countrycode中顯示語言
SELECT countrycode ,LANGUAGE FROM countrylanguage; --三、連表 SELECT ci.NAME ,ci.countrycode ,ci.population,cl.language FROM city AS ci , countrylanguage AS cl WHERE ci.countrycode ='CHN' AND ci.CountryCode=cl.CountryCode; -- name 能夠直接使用, SELECT NAME,ci.countrycode ,cl.language ,ci.population FROM city ci , countrylanguage cl WHERE ci.countrycode='chn' AND ci.`CountryCode`=cl.countrycode; -- 使用NATURAL JOIN SELECT NAME,countrycode ,LANGUAGE ,population FROM city NATURAL JOIN countrylanguage WHERE population > 10000000 ORDER BY population; -- 使用JOIN USING SELECT NAME,countrycode ,LANGUAGE ,population FROM city JOIN countrylanguage USING(countrycode); NATURAL JOIN 和 JOIN USING 都不經常使用
---- 查詢青島這個城市,所在的國傢俱體叫什麼名字 使用 JOIN ON DESC city DESC country --一、查看青島 SELECT NAME,countrycode FROM city WHERE NAME='qingdao'; --二、查看中國城市名 SELECT NAME FROM country WHERE CODE='CHN'; --三、連表 -------------------------------- SELECT ci.name ,ci.countrycode,ci.population ,co.name FROM city AS ci JOIN country AS co ON ci.countrycode=co.code AND ci.name='qingdao'; ---------------------------------
group by +聚合函數(avg()、max()、min()、sum()) SELECT countrycode ,SUM(population) FROM city WHERE countrycode = 'chn' GROUP BY countrycode; union 用來替換 orin() 性能更好些 SELECT * FROM world.city WHERE countrycode IN ('CHN','JPN'); 改寫爲: SELECT * FROM world.city WHERE countrycode ='CHN' union SELECT * FROM world.city WHERE countrycode ='JPN';

兩個SQL須要是相同的結

 

五、SQL字符集

尤爲是在進行數據庫遷移的時候,必定要注意字符集

• 字符集(Charset): 
  是一個系統支持的全部抽象字符的集合。
  字符是各類文字和符號的總稱, 包括各國家文字、標點符號、圖形符號、數字等。

 

• MySQL數據庫的字符集: 
  – 字符集(CHARACTER)
  – 校對規則(COLLATION)
• MySQL中常見的字符集:
  – UTF8 ,utf8mb4
  – LATIN1 編譯默認的,開發者的母語
  – GBK
• 常見校對規則: 即排序規則
  – ci:大小寫不敏感 aA-zZ
  – cs或bin:大小寫敏感 a-z A-Z
• 咱們能夠使用如下命令查看:
  – show charset;
  – show collation;
字符集的級別
• 操做系統級別
  控制的是系統相關的顯示,和一些依賴於操做系統的應用
  source /etc/sysconfig/i18n
  [root@db02 logs]# echo $LANG
  zh_CN.UTF-8
• 操做系統客戶端級別(SSH)
  控制的是用戶的輸入和展現
• 服務端字符集
  控制的是,存到mysql中時,字符集控制
• MySQL實例級別
  – 方法1:在編譯安裝時候就指定以下服務器端字符集。
  cmake .
  -DDEFAULT_CHARSET=utf8 \
  -DDEFAULT_COLLATION=utf8_general_ci \
  -DWITH_EXTRA_CHARSETS=all \
  – 方法2:
  [mysqld] character-set-server=utf8

• 數據庫中的庫級別
  CREATE DATABASE `oldboy` /*!40100 DEFAULT CHARACTER SET utf8 */
  create database oldboy DEFAULT CHARACTER SET UTF8 DEFAULT COLLATE
  = utf8_general_ci;
• 獲取幫助並查詢
  help create database;
  show character set;
• 表級別(含字段級別)
  CREATE TABLE `test` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `name` char(20) NOT NULL,
  PRIMARY KEY (`id`)
  ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8
• MySQL客戶端級別(鏈接及返回結果)
  方法1:臨時生效單條命令法。
  mysql> set names utf8;
  Query OK, 0 rows affected (0.00 sec)
  方法2:經過修改my.cnf實現修改mysql客戶端的字符集,配置方法以下。
  [client]
  default-character-set=utf8
• 程序代碼級別
• 生產環境更改數據庫(含數據)字符集的方法
  alter database oldboy CHARACTER SET utf8 collate
  utf8_general_ci;
  alter table t1 CHARACTER SET latin1;
注意:更改字符集時,必定要保證由小往大改,後者必須是前者的嚴格超集。

 

六、數據類型介紹

• 數據類型介紹

 

• 數據類型設置

建立帶有數據類型的表

數值數據類型

注意事項:

  • 數據類型所表示的值的範圍
  • 列值所需的空間量
  • 列精度和範圍(浮點數和定點數)

種類:

  • 整數:整數
  • 浮點數:小數
  • 定點數:精確值數值
  • BIT:位字段值

字符串數據類型

  • 表示給定字符集中的一個字母數字字符序列
  • 用於存儲文本或二進制數據
  • 幾乎在每種編程語言中都有實現
  • 支持字符集和整理
  • 屬於如下其中一類
    • 文本:真實的非結構化字符串數據類型
    • 整數:結構化字符串類型

二進制字符串數據類型

  • 字節序列
    • 二進制位按八位分組
  • 存儲二進制值,例如:
    • 編譯的計算機程序和應用程序
    • 圖像和聲音文件
  • 字符二進制數據類型的類:
    • 二進制:固定長度和可變長度的二進制字符串
    • – BLOB:二進制數據的可變長度非結構化集合

時間數據類型

經常使用的是datetime和timestamp

• 列屬性

列屬性的類別:

  • 數值:適用於數值數據類型(BIT 除外)
  • 字符串:適用於非二進制字符串數據類型
  • 常規:適用於全部數據類型

primary key:主鍵:非空、惟一

unique:惟一

• 數據類型的字符集用法

 

• 選擇適當的數據類型

• 考慮哪些數據類型和字符集能夠最大限度地減小存儲和磁盤 I/O。 
• 使用固定長度數據類型:
  – 若是存儲的全部字符串值的長度相同
• 使用可變長度數據類型:
  – 若是存儲的字符串值不一樣
  – 對於多字節字符集
• 對於頻繁使用的字符,使用佔用空間較少的多字節字符集。
  – 使用基本多文種平面 (Basic Multilingual Plane, BMP) 以外的其餘 Unicode 字符集

 

七、元數據獲取-INFORMATION_SCHEMA數據庫介紹

INFORMATION_SCHEMA,經過這個庫提供的一些視圖,咱們能夠很是輕鬆的去獲取

對於數據庫的,統計信息。咱們也把這些叫作元數據

對於數據庫,兩個信息

  • 數據行:咱們使用DDL、DCL、DQL操做的數據
  • 元數據:定義數據的數據
    • 庫的名字、屬性
    • 表名、屬性
    • 庫狀態,表狀態...

• 元數據訪問方式介紹

• 查詢 INFORMATION_SCHEMA 數據庫表。 
  – 其中包含 MySQL 數據庫服務器所管理的全部對象的相關數據
• 使用 SHOW 語句。
  – 用於獲取數據庫和表信息的 MySQL 專用語句
• 使用 DESCRIBE(或 DESC)語句。
  – 用於檢查表結構和列屬性的快捷方式
• 使用 mysqlshow 客戶端程序。
  – SHOW 語法的命令行程序

 

• INFORMATION_SCHEMA 數據庫的結構

• 充當數據庫元數據的中央系統信息庫 
  – 模式和模式對象
  – 服務器統計信息(狀態變量、設置、鏈接)
• 採用表格式以實現靈活訪問
  – 使用任意 SELECT 語句
• 是「虛擬數據庫」
  – 表並不是「真實」表(基表),而是「系統視圖」
  – 根據當前用戶的特權動態填充表

 

INFORMATION_SCHEMA 表

列出 INFORMATION_SCHEMA 數據庫中全部的表: 
mysql> use information_schema
mysql> show tables;
| CHARACTER_SETS |
| COLLATIONS |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS |
| COLUMN_PRIVILEGES |
...
| USER_PRIVILEGES |
| VIEWS

 

查看數據庫一共有多少張表

查看元數據中的表的元數據
mysql> desc tables; +-----------------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------------+---------------------+------+-----+---------+-------+ | TABLE_CATALOG | varchar(512) | NO | | | | | TABLE_SCHEMA | varchar(64) | NO | | | | | TABLE_NAME | varchar(64) | NO | | | | | TABLE_TYPE | varchar(64) | NO | | | | | ENGINE | varchar(64) | YES | | NULL | | | VERSION | bigint(21) unsigned | YES | | NULL | | | ROW_FORMAT | varchar(10) | YES | | NULL | | | TABLE_ROWS | bigint(21) unsigned | YES | | NULL | | | AVG_ROW_LENGTH | bigint(21) unsigned | YES | | NULL | | | DATA_LENGTH | bigint(21) unsigned | YES | | NULL | | | MAX_DATA_LENGTH | bigint(21) unsigned | YES | | NULL | | | INDEX_LENGTH | bigint(21) unsigned | YES | | NULL | | | DATA_FREE | bigint(21) unsigned | YES | | NULL | | | AUTO_INCREMENT | bigint(21) unsigned | YES | | NULL | | | CREATE_TIME | datetime | YES | | NULL | | | UPDATE_TIME | datetime | YES | | NULL | | | CHECK_TIME | datetime | YES | | NULL | | | TABLE_COLLATION | varchar(32) | YES | | NULL | | | CHECKSUM | bigint(21) unsigned | YES | | NULL | | | CREATE_OPTIONS | varchar(255) | YES | | NULL | | | TABLE_COMMENT | varchar(2048) | NO | | | | +-----------------+---------------------+------+-----+---------+-------+ 21 rows in set (0.00 sec) 查看數據庫一共有多少張表 mysql> select count(TABLE_NAME) from tables; +-------------------+ | count(TABLE_NAME) | +-------------------+ | 142 | +-------------------+ 1 row in set (0.01 sec)

 

• 使用可用命令查看元數據

對 INFORMATION_SCHEMA 使用 SELECT

• 指定要檢索哪一個表和哪些列。 
• 經過使用 WHERE 子句,可僅檢索特定條件。 
• 對結果分組或排序。 
• 使用 JOIN、UNION 和子查詢。 
• 將結果檢索到其餘表中。 
• 基於 INFORMATION_SCHEMA 表建立視圖
例子:
查看world庫下的全部表的表名,引擎 mysql
> SELECT TABLE_NAME, ENGINE   -> FROM INFORMATION_SCHEMA.TABLES   -> WHERE TABLE_SCHEMA = 'world';
mysql
> SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME   -> FROM INFORMATION_SCHEMA.COLUMNS   -> WHERE DATA_TYPE = 'set';
mysql
> SELECT CHARACTER_SET_NAME, COLLATION_NAME   -> FROM INFORMATION_SCHEMA.COLLATIONS   -> WHERE IS_DEFAULT = 'Yes';
每一個庫下面的表數量的統計 mysql
> SELECT TABLE_SCHEMA, COUNT(*)   -> FROM INFORMATION_SCHEMA.TABLES   -> GROUP BY TABLE_SCHEMA;
只能查詢 mysql
> DELETE FROM INFORMATION_SCHEMA.VIEWS; ERROR 1044 (42000): Access denied for user 'root'@'localhost' to database 'information_schema'

 

• SHOW 語句和 INFORMATION_SCHEMA 表之間的區別

show是基於information_schema表提早作好的視圖函數

show語句

• SOHW databases:列出全部數據庫 
• SHOW TABLES:列出默認數據庫中的表
• SHOW TABLES FROM <database_name>:列出指定數據庫中的表
• SHOW COLUMNS FROM <table_name>:顯示錶的列結構
• SHOW INDEX FROM <table_name>:顯示錶中有關索引和索引列的信息
• SHOW CHARACTER SET:顯示可用的字符集及其默認整理
• SHOW COLLATION:顯示每一個字符集的整理
• SHOW STATUS:列出當前數據庫狀態
• SHOW VARIABLES:列出數據庫中的參數定義值

上面的命令重點掌握

配合模糊查詢獲得咱們須要的信息

mysql> show status like '%lock%';
+------------------------------------------+-------+
| Variable_name                            | Value |
+------------------------------------------+-------+
| Com_lock_tables                          | 0     |
| Com_unlock_tables                        | 0     |
| Handler_external_lock                    | 0     |
| Innodb_row_lock_current_waits            | 0     |
| Innodb_row_lock_time                     | 0     |
| Innodb_row_lock_time_avg                 | 0     |
| Innodb_row_lock_time_max                 | 0     |
| Innodb_row_lock_waits                    | 0     |
| Key_blocks_not_flushed                   | 0     |
| Key_blocks_unused                        | 6698  |
| Key_blocks_used                          | 0     |
| Performance_schema_locker_lost           | 0     |
| Performance_schema_rwlock_classes_lost   | 0     |
| Performance_schema_rwlock_instances_lost | 0     |
| Qcache_free_blocks                       | 1     |
| Qcache_total_blocks                      | 1     |
| Table_locks_immediate                    | 119   |
| Table_locks_waited                       | 0     |
+------------------------------------------+-------+
18 rows in set (0.00 sec)

 

• mysqlshow 客戶端工具使用

顯示有關數據庫和表的結構的信息

  – 與 SHOW 語句類似

通常語法:

shell> mysqlshow [options] [db_name [table_name [column_name]]]

選項能夠是標準鏈接參數。

顯示全部數據庫或特定數據庫、表和/或列的相關信息:

 

• 使用 INFORMATION_SCHEMA 表建立 shell 命令和 SQL 語句

使用 INFORMATION_SCHEMA 表建立 SQL 語句

 

 

使用 INFORMATION_SCHEMA 表建立 Shell 命令

備份的普通寫法:mysqldump -uroot -ppizza123 world country >> /backup/world.bak.sql

若是有100條,要寫100次

能夠在NFORMATION_SCHEMA中查到world下的全部表

select table_schema,country  from  tables  where  table  schema='world';

請按照下面的例子,按照需求拼接上面的命令並輸出到文件

注意:空格也是要標識出來的

八、索引管理及執行計劃

索引類型介紹

  • BTREE:B+樹索引   ------>重點和經常使用
  • HASH:HASH索引
  • FULLTEXT:全文索引
  • RTREE:R樹索引

索引管理

  • 索引創建在表的列上(字段)的。
  • 在where後面的列創建索引纔會加快查詢速度。
  • pages<---索引(屬性)<----查數據。
  • 索引分類:
    • 主鍵索引       開發前就決定了
    • 普通索引*****
    • 惟一索引  開發前就決定了
  • 添加索引:
    • alter table test add index index_name(name);
    • create index index_name on test(name);

查詢索引信息

mysql> desc test;
+-------+------------+------+-----+---------+----------------+
| Field | Type       | Null | Key | Default | Extra          |
+-------+------------+------+-----+---------+----------------+
| id    | int(11)    | NO   | PRI | NULL    | auto_increment |
| name  | char(20)   | NO   | MUL | NULL    |                |
| state | tinyint(2) | NO   |     | 1       |                |
+-------+------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

刪除索引

mysql> alter table test drop index index_name;
Query OK, 0 rows affected (0.20 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc test;
+-------+------------+------+-----+---------+----------------+
| Field | Type       | Null | Key | Default | Extra          |
+-------+------------+------+-----+---------+----------------+
| id    | int(11)    | NO   | PRI | NULL    | auto_increment |
| name  | char(20)   | NO   |     | NULL    |                |
| state | tinyint(2) | NO   |     | 1       |                |
+-------+------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

 

或者drop index  index_name on test;

查詢

desc test;
或
show index from test\G

 

MySQL中的約束索引

1、主鍵索引:只能有一個主鍵。
    主鍵索引:列的內容是惟一值,高中學號.
    表建立的時候至少要有一個主鍵索引,最好和業務無關。
  走主鍵索引的查詢效率是最高的
2、普通索引 加快查詢速度,工做中優化數據庫的關鍵。 在合適的列上創建索引,讓數據查詢更高效。 create index index_name on test(name); alter table test add index index_name(name); 用了索引,查一堆內容。 在where條件關鍵字後面的列創建索引纔會加快查詢速度. select id,name from test where state=1 order by id group by name; 3、惟一索引 內容惟一,但不是主鍵。 create unique index index_name on test(name);

建立主鍵索引

1.創建表時
CREATE TABLE `test` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `name` char(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=UTF8;

2.創建表後增長
CREATE TABLE `test` (
  `id` int(4) NOT NULL,
  `name` char(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
增長自增主鍵
alter table test change id id int(4) primary key not null auto_increment;

 

使用字段前綴建立索引及聯合索引

1.前綴索引:根據字段的前N個字符創建索引
    create index index_name on test(name(8));
2.聯合索引:多個字段創建一個索引。
where a女生 and b身高165 and c身材好
index(a,b,c)
特色:前綴生效特性。
a,ab,abc  能夠走索引。
b ac bc c 不走索引。
原則:把最經常使用來做爲條件查詢的列放在前面。

實例:
alter table test add sex char(4) not null;
create index ind_name_sex on test(name,sex);
explain select id,name from test where name='oldboy'\G
explain select id,name from test where sex='nv'\G
explain select id,name from test where name='oldgirl' and sex='nv'\G

聯合主鍵是聯合索引的特殊形式:
PRIMARY KEY (`Host`,`User`)
alter table test add sex char(4) not null;
create index ind_name_sex on test(name,sex);
前綴加聯合索引
create index index_name on test(name(8),sex(2));

 

用expain查看SQL的執行計劃

沒有索引
mysql> explain select id,name from test where name='pizza'\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: ALL 表示MySQL在表中找到所需行的方式,又稱「訪問類型」 possible_keys: NULL key: NULL key_len: NULL 越小越好 ref: NULL rows: 1 Extra: Using where 1 row in set (0.08 sec) 常見的type
ALL、index、range、ref、eq_ref、const、system、null
從左到右,性能從最差到最好
mysql> alter table test add index index_name(name); Query OK, 0 rows affected (0.14 sec) Records: 0 Duplicates: 0 Warnings: 0
有索引 mysql> explain select id,name from test where name='pizza'\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: ref possible_keys: index_name key: index_name key_len: 60 ref: const rows: 1 Extra: Using where; Using index 1 row in set (0.00 sec)


explain  select SQL_NO_CACHE  * from test where name='oldboy'\G
SQL_NO_CACHE的做用是禁止緩存查詢結果。

explain中各type類型的詳解

ALL:
  Full Table Scan, MySQL將遍歷全表以找到匹配的行

  若是顯示ALL,說明:
  查詢沒有走索引:
      1、語句自己的問題    2、索引的問題,沒創建索引 index:
  Full Index Scan,index與ALL區別爲index類型只遍歷索引樹   例子:   explain select count(*) from stu ; range:
  索引範圍掃描,對索引的掃描開始於某一點,返回匹配值域的行。   顯而易見的索引範圍掃描是帶有between或者where子句裏帶有<,>查詢。   where 條件中有範圍查詢或模糊查詢時   > < >= <= between and in () or   like 'xx%'   當mysql使用索引去查找一系列值時,例如IN()和OR列表,也會顯示range(範圍掃描)
  固然性能上面是有差別的。 ref:
  使用非惟一索引掃描或者惟一索引的前綴掃描,返回匹配某個單獨值的記錄行   where stu_name='xiaoming'   explain select * from stu where stu_name='aa'; eq_ref:
  相似ref,區別就在使用的索引是惟一索引,對於每一個索引鍵值,表中只有一條記錄匹配,簡單來講,   就是多表鏈接中使用primary key或者 unique key做爲關聯條件   join條件使用的是primary key或者 unique key const、system:
  當MySQL對查詢某部分進行優化,並轉換爲一個常量時,使用這些類型訪問。   如將主鍵置於where列表中,MySQL就能將該查詢轉換爲一個常量   explain select * from city where id=1; NULL:
  MySQL在優化過程當中分解語句,執行時甚至不用訪問表或索引,   例如從一個索引列裏選取最小值能夠經過單獨索引查找完成。
  或者走的緩存中已經存在的

explain中的Extra

避免出現
Using temporary
Using filesort
Using join buffer
出現的緣由是:
排序   order by  ,group by ,distinct,排序條件上沒有索引
explain select * from city where countrycode='CHN' order by population;
解決辦法:
在join 的條件列上沒有創建索引
將前一個結果保存爲視圖,再排序

數據庫索引的設計原則

爲了使索引的使用效率更高,在建立索引時
必須考慮在哪些字段上建立索引和建立什麼類型的索引。 那麼索引設計原則又是怎樣的
? 1.選擇惟一性索引 惟一性索引的值是惟一的,能夠更快速的經過該索引來肯定某條記錄。 例如,學生表中學號是具備惟一性的字段。爲該字段創建惟一性索引能夠很快的肯定某個學生的信息。 若是使用姓名的話,可能存在同名現象,從而下降查詢速度。 主鍵索引和惟一鍵索引,在查詢中使用是效率最高的 2.爲常常須要排序、分組和聯合操做的字段創建索引 常常須要ORDER BY、GROUP BY、DISTINCT和UNION等操做的字段,排序操做會浪費不少時間。 若是爲其創建索引,能夠有效地避免排序操做。 3.爲常做爲查詢條件的字段創建索引 若是某個字段常常用來作查詢條件,那麼該字段的查詢速度會影響整個表的查詢速度。所以, 爲這樣的字段創建索引,能夠提升整個表的查詢速度。 可是,是否是真的適合去作索引,還要去統計一下這個列,去重以後的數量
和總行數對比,佔的數量過小,好比性別,就不合適做爲索引列
select count(DISTINCT population ) from city; select count(*) from city; 4.儘可能使用前綴來索引 若是索引字段的值很長,最好使用值的前綴來索引。例如,TEXT和BLOG類型的字段,進行全文檢索 會很浪費時間。若是隻檢索字段的前面的若干個字符,這樣能夠提升檢索速度。 ------------------------以上的是重點關注的,如下是能保證則保證的-------------------- 5.限制索引的數目 索引的數目不是越多越好。每一個索引都須要佔用磁盤空間,索引越多,須要的磁盤空間就越大。 修改表時,對索引的重構和更新很麻煩。越多的索引,會使更新表變得很浪費時間。 6.儘可能使用數據量少的索引 若是索引的值很長,那麼查詢的速度會受到影響。例如,對一個CHAR(100)類型的字段進行全文 檢索須要的時間確定要比對CHAR(10)類型的字段須要的時間要多。 7.刪除再也不使用或者不多使用的索引 表中的數據被大量更新,或者數據的使用方式被改變後,原有的一些索引可能再也不須要。數據庫管理 員應當按期找出這些索引,將它們刪除,從而減小索引對更新操做的影響。 ------------------------------2、開發規範----------------------------------------- 不走索引的狀況: 重點關注: 1) 沒有查詢條件,或者查詢條件沒有創建索引 select * from tab; 全表掃描。 select * from tab where 1=1; 在業務數據庫中,特別是數據量比較大的表。 是沒有全表掃描這種需求。 1、對用戶查看是很是痛苦的。 2、對服務器來說毀滅性的。 (1select * from tab; SQL改寫成如下語句: selec * from tab order by price limit 10 須要在price列上創建索引 (2select * from tab where name='zhangsan' name列沒有索引 改: 1、換成有索引的列做爲查詢條件 2、將name列創建索引 2) 查詢結果集是原表中的大部分數據,應該是30%以上。 查詢的結果集,超過了總數行數30%,優化器以爲就沒有必要走索引了。 假如:tab表 id,name id:1-100w ,id列有索引 select * from tab where id>500000; 若是業務容許,能夠使用limit控制。 怎麼改寫 ? 結合業務判斷,有沒有更好的方式。若是沒有更好的改寫方案 儘可能不要在mysql存放這個數據了。放到redis裏面。 3) 索引自己失效,統計數據不真實 索引有自我維護的能力。 對於表內容變化比較頻繁的狀況下,有可能會出現索引失效。 4) 查詢條件使用函數在索引列上,或者對索引列進行運算,運算包括(+,-,*,/,! 等) 例子: 錯誤的例子:select * from test where id-1=9; 正確的例子:select * from test where id=10; 5)隱式轉換致使索引失效.這一點應當引發重視.也是開發中常常會犯的錯誤. 因爲表的字段tu_mdn定義爲varchar2(20),但在查詢時把該字段做爲number類型以where條件傳給數據庫, 這樣會致使索引失效. 錯誤的例子:select * from test where tu_mdn=13333333333; 正確的例子:select * from test where tu_mdn='13333333333'; ------------------------ mysql> alter table tab add index inx_tel(telnum); Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> mysql> desc tab; +--------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | name | varchar(20) | YES | | NULL | | | telnum | varchar(20) | YES | MUL | NULL | | +--------+-------------+------+-----+---------+-------+ 3 rows in set (0.01 sec) mysql> select * from tab where telnum='1333333'; +------+------+---------+ | id | name | telnum | +------+------+---------+ | 1 | a | 1333333 | +------+------+---------+ 1 row in set (0.00 sec) mysql> select * from tab where telnum=1333333; +------+------+---------+ | id | name | telnum | +------+------+---------+ | 1 | a | 1333333 | +------+------+---------+ 1 row in set (0.00 sec) mysql> explain select * from tab where telnum='1333333'; +----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+ | 1 | SIMPLE | tab | ref | inx_tel | inx_tel | 63 | const | 1 | Using index condition | +----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+ 1 row in set (0.00 sec) mysql> explain select * from tab where telnum=1333333; +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | tab | ALL | inx_tel | NULL | NULL | NULL | 2 | Using where | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ 1 row in set (0.00 sec) mysql> explain select * from tab where telnum=1555555; +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | tab | ALL | inx_tel | NULL | NULL | NULL | 2 | Using where | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ 1 row in set (0.00 sec) mysql> explain select * from tab where telnum='1555555'; +----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+ | 1 | SIMPLE | tab | ref | inx_tel | inx_tel | 63 | const | 1 | Using index condition | +----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+ 1 row in set (0.00 sec) mysql> ------------------------ 6) <> ,not in 不走索引 EXPLAIN SELECT * FROM teltab WHERE telnum <> '110'; EXPLAIN SELECT * FROM teltab WHERE telnum NOT IN ('110','119'); ------------ mysql> select * from tab where telnum <> '1555555'; +------+------+---------+ | id | name | telnum | +------+------+---------+ | 1 | a | 1333333 | +------+------+---------+ 1 row in set (0.00 sec) mysql> explain select * from tab where telnum <> '1555555'; ----- 單獨的>,<,in 有可能走,也有可能不走,和結果集有關,儘可能結合業務添加limit or或in 儘可能改爲union EXPLAIN SELECT * FROM teltab WHERE telnum IN ('110','119'); 改寫成: EXPLAIN SELECT * FROM teltab WHERE telnum='110' UNION ALL SELECT * FROM teltab WHERE telnum='119' ----------------------------------- 7) like "%_" 百分號在最前面不走 EXPLAIN SELECT * FROM teltab WHERE telnum LIKE '31%' 走range索引掃描 EXPLAIN SELECT * FROM teltab WHERE telnum LIKE '%110' 不走索引 %linux%類的搜索需求,能夠使用elasticsearch %linux培訓% 8) 單獨引用複合索引裏非第一位置的索引列. 列子: 複合索引: DROP TABLE t1 CREATE TABLE t1 (id INT,NAME VARCHAR(20),age INT ,sex ENUM('m','f'),money INT); ALTER TABLE t1 ADD INDEX t1_idx(money,age,sex); DESC t1 SHOW INDEX FROM t1 走索引的狀況測試: EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE money=30 AND age=30 AND sex='m'; EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE money=30 AND age=30 ; EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE money=30 AND sex='m'; ----->部分走索引 不走索引的: EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE age=20 EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE age=30 AND sex='m'; EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE sex='m'; ------------------------------------------------

索引的企業應用場景

企業SQL優化思路:
1、把一個大的不使用索引的SQL語句按照功能進行拆分
2、長的SQL語句沒法使用索引,能不能變成2條短的SQL語句讓它分別使用上索引。
3、對SQL語句功能的拆分和修改
4、減小「爛」SQL
    由運維(DBA)和開發交流(確認),共同肯定如何改,最終由DBA執行
5、制定開發流程    

不適合走索引的場景:
1、惟一值少的列上不適合創建索引或者創建索引效率低。例如:性別列
2、小表能夠不創建索引,100條記錄。
3、對於數據倉庫,大量全表掃描的狀況,建索引反而會慢

查看錶的惟一值數量:
select count(distinct user) from mysql.user;
select count(distinct user,host) from mysql.user;     

建索引流程:
1、找到慢SQL。
   show processlist;
   記錄慢查詢日誌。
2、explain select句,條件列多。
3、查看錶的惟一值數量:
select count(distinct user) from mysql.user;
select count(distinct user,host) from mysql.user;
條件列多。能夠考慮創建聯合索引。
4、創建索引(流量低谷)
force index
5、拆開語句(和開發)。
6、like '%%'不用mysql     

九、MySQL的存儲引擎

1、存儲引擎的介紹

文件系統:
  - 操做系統組織和存取數據的一種機制。
  - 文件系統是一種軟件。
類型:ext2 3 4 ,xfs 數據
  - 無論使用什麼文件系統,數據內容不會變化
  - 不一樣的是,存儲空間、大小、速度。
MySQL引擎:
  - 能夠理解爲,MySQL的「文件系統」,只不過功能更增強大。
MySQL引擎功能:
  - 除了能夠提供基本的存取功能,還有更多功能事務功能、鎖定、備份和恢復、優化以及特殊功能。

2MySQL中的存儲引擎分類

MySQL 提供如下存儲引擎:
  - InnoDB
  - MyISAM
InnoDB 和 MyISAM最經常使用   - MEMORY   - ARCHIVE   - FEDERATED   - EXAMPLE   - BLACKHOLE   - MERGE   - NDBCLUSTER   - CSV 還能夠使用第三方存儲引擎(TokuDB)。用於zabbix和爬蟲的存儲,inno操做頗有效,壓縮性

Innodb功能總覽

重點理解:事務、鎖定粒度(行)、備份和恢復、自動故障恢復

3MySQL存儲引擎設置

查看

1、使用 SELECT 確認會話存儲引擎:
  SELECT @@default_storage_engine;
  查看全部的存儲引擎
  show engines;
2、使用 SHOW 確認每一個表的存儲引擎:   SHOW CREATE TABLE City\G   SHOW TABLE STATUS LIKE 'CountryLanguage'\G 3、使用 INFORMATION_SCHEMA 確認每一個表的存儲引擎: SELECT TABLE_NAME, ENGINE
  FROM INFORMATION_SCHEMA.TABLES
  WHERE TABLE_SCHEMA = 'world'
  AND TABLE_SCHEMA = 'world';
+-----------------+--------+
| TABLE_NAME      | ENGINE |
+-----------------+--------+
| city            | InnoDB |
| country         | InnoDB |
| countrylanguage | InnoDB |
| test            | InnoDB |
+-----------------+--------+
四、mysql> show variables like '%engine%';
+----------------------------+--------+
| Variable_name              | Value  |
+----------------------------+--------+
| default_storage_engine     | InnoDB |
| default_tmp_storage_engine | InnoDB |
| storage_engine             | InnoDB |
+----------------------------+--------+
3 rows in set (0.00 sec)

下列查詢語句都對應查詢了什麼?
show engines;
show create table city;
show table status like 'city'\G
select table_schema,table_name,engine from information_schema.tables where table_schema='world';
select table_schema,table_name,engine from information_schema.tables where table_schema='mysql';
select table_schema,table_name,engine from information_schema.tables where engine='csv';

 

設置

0、在編譯的時候也能夠設置
1
、在啓動配置文件中設置服務器存儲引擎:
  vim /etc/my.cnf [mysqld] default
-storage-engine=<Storage Engine> 2、使用 SET 命令爲當前客戶機會話設置: SET @@storage_engine=<Storage Engine>; 3、在 CREATE TABLE 語句指定: CREATE TABLE t (i INT) ENGINE = <Storage Engine>;

4MySQL Innodb引擎存儲結構

表空間的概念由orcle引入

系統共享表空間

InnoDB 系統表空間
   - 默認狀況下,InnoDB 元數據、撤消日誌和緩衝區存儲在系統「表空間」中。
   - 這是單個邏輯存儲區域,能夠包含一個或多個文件。
   - 每一個文件能夠是常規文件或原始分區。
   - 最後的文件能夠自動擴展。 
如今已經不用於生產數據的存儲了,只用於存系統文件。

共享表空間設置

經過添加數據文件增長表空間大小。
在 my.cnf 文件中使用 innodb_data_file_path 選項。 
    [mysqld]
    innodb_data_file_path=datafile_spec1[;datafile_spec2]...
配置示例:建立一個表空間,
其中包含一個名爲 ibdata1 且大小爲
50 MB(固定)的數據文件和
一個名爲 ibdata2 且大小爲 50 MB(自動擴展)的數據文件: [mysqld] innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend 默認狀況下將文件放置在 data 目錄中。 若是須要,顯式指定文件位置。
innodb_data_file_path=ibdata1:12M;ibdata2:50M:autoextend    ----錯誤的配置XXX
innodb_data_file_path=ibdata1:76M;ibdata2:50M:autoextend    ----正確的配置,看實際而定
查看錶空間設置
修改以前:
mysql> show variables like '%data%';
+-------------------------------+---------------------------------+
| Variable_name                 | Value                           |
+-------------------------------+---------------------------------+
| character_set_database        | utf8                            |
| collation_database            | utf8_general_ci                 |
| datadir                       | /application/mysql-5.6.43/data/ |
| innodb_data_file_path         | ibdata1:12M:autoextend          |
修改以前先看一下,文件的大小,不然就是錯誤的修改,將致使數據庫啓動時報錯,沒法啓動

[root@web01 data]# du -h ibdata1
12M    ibdata1
這第一個的大小,不能大也不能小
innodb_data_file_path=ibdata1:12M;ibdata2:50M:autoextend
修改後,重啓,再次查看
mysql> show variables like '%data%';
+-------------------------------+------------------------------------+
| Variable_name                 | Value                              |
+-------------------------------+------------------------------------+
| character_set_database        | utf8                               |
| collation_database            | utf8_general_ci                    |
| datadir                       | /application/mysql-5.6.43/data/    |
| innodb_data_file_path         | ibdata1:12M;ibdata2:50M:autoextend |
已經改變了!

最好在裝完軟件後就設置好

數據獨立表空間

除了系統表空間以外,InnoDB 還在數據庫目錄中建立另外的表空間,用於每一個 InnoDB 表的 .ibd 文件。
    InnoDB 建立的每一個新表在數據庫目錄中設置一個 .ibd 文件來搭配表的 .frm 文件。
  固然,也會想系統空間存放元數據信息(存在哪一個庫,空間佔用是多少,索引信息) 能夠使用 innodb_file_per_table 選項控制此設置, 更改該設置僅會更改已建立的新表的默認值。 注:在mysql5.6開始,默認的配置爲:
| innodb_file_per_table | ON |

在mysql內部有專門刪除或者導入ibd的功能
  alter table test discard tablespace;

5MySQL中的事務

簡介

一組數據操做執行步驟,這些步驟被視爲一個工做單元
  - 用於對多個語句進行分組
  - 能夠在多個客戶機併發訪問同一個表中的數據時使用
全部步驟都成功或都失敗
  - 若是全部步驟正常,則執行
  - 若是步驟出現錯誤或不完整,則取消

事務的特性-ACID

Atomic(原子性)
    全部語句做爲一個單元所有成功執行或所有取消。
Consistent(一致性)
    若是數據庫在事務開始時處於一致狀態,則在執行該事務期間將保留一致狀態。 
Isolated(隔離性)
    事務之間不相互影響。
Durable(持久性)
    事務成功完成後,所作的全部更改都會準確地記錄在數據庫中。所作的更改不會丟失。

Innodb存儲引擎--事務處理流程舉例

標準的事務語句,就只是DML語句,insert、update、delete

只要看到有DML標準語句,系統不須要begin就開始事務了,這是5.6後的新特性

START TRANSACTION(或 BEGIN):顯式開始一個新事務
SAVEPOINT:分配事務過程當中的一個位置,以供未來引用 COMMIT:永久記錄當前事務所作的更改,說明事務要提交,要完成了
ROLLBACK:取消當前事務所作的更改 ROLLBACK TO SAVEPOINT:取消在 savepoint 以後執行的更改 RELEASE SAVEPOINT:刪除 savepoint 標識符 SET AUTOCOMMIT:爲當前鏈接禁用或啓用默認 autocommit 模式

查看autocommit的狀態
mysql> show variables like '%autocommit%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.00 sec)
在事務性的應用場景下,要改爲OFF,避免寫一句就提交,寫一句就提交
查看全局的
show global variables like '%autocommit%';

Autocommit 模式設置

在MySQL5.5開始,開啓事務時再也不須要begin或者start transaction語句。
而且,默認是開啓了Autocommit模式,做爲一個事務隱式提交每一個語句。 在有些業務繁忙企業場景下,這種配置可能會對性能產生很大影響,但對於安全性上有很大提升。 未來,咱們須要去權衡咱們的業務需求去調整是否自動提交。 咱們能夠經過如下命令進行修改關閉(0是關閉,1是開啓):   SET GLOBAL AUTOCOMMIT
=0; - 全部新建會話
  SET SESSION AUTOCOMMIT=0; - 當前會話   SELECT @@AUTOCOMMIT; - 查看設置結果 咱們也能夠修改配置文件讓其永久生效: vim /etc/my.cnf [mysqld] AUTOCOMMIT=0

其餘觸發隱式commit的狀況

用於隱式提交的 SQL 語句:
    START TRANSACTION,也就是以前有一個Begin或者START TRANSACTION
    SET AUTOCOMMIT = 1 
致使提交的非事務語句:
    DDL語句:    (ALTER、CREATE 和 DROP)
    DCL語句:    (GRANT、REVOKE 和 SET PASSWORD)
    鎖定語句:(LOCK TABLES 和 UNLOCK TABLES)
致使隱式提交的語句示例:
    TRUNCATE TABLE
    LOAD DATA INFILE
    SELECT FOR UPDATE

事務日誌redo

Redo是什麼?    
    redo,顧名思義「重作日誌」,是事務日誌的一種。
做用是什麼?
    在事務ACID過程當中,實現的是「D」持久化的做用。
記錄數據頁的變化

 

每次都提交,過多的IO操做會影響性能,因此有了Redo

事務日誌undo

undo是什麼?    
undo,顧名思義「回滾日誌」,是事務日誌的一種。
做用是什麼?
在事務ACID過程當中,實現的是「A、C」原子性和一致性的做用。

 

6MySQL中的鎖

什麼是「鎖」?
「鎖」顧名思義就是鎖定的意思。
「鎖」的做用是什麼?
在事務ACID過程當中,「鎖」和「隔離級別」一塊兒來實現「I」隔離性的做用。
避免爭搶資源
鎖的粒度:
一、MyIasm:低併發鎖——表級鎖
二、Innodb:高併發鎖——行級鎖

四種隔離級別

READ UNCOMMITTED        
  容許事務查看其餘事務所進行的未提交更改
READ COMMITTED
   容許事務查看其餘事務所進行的已提交更改
REPEATABLE READ******
   確保每一個事務的 SELECT 輸出一致
  InnoDB 的默認級別 SERIALIZABLE 將一個事務的結果與其餘事務徹底隔離

mysql> show variables like '%iso%';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tx_isolation  | REPEATABLE-READ |
+---------------+-----------------+

十、MySQL日誌管理

1MySQL日誌類型簡介

2MySQL錯誤日誌配置及查看

配置方法:
[mysqld]
log-error=/data/mysql/mysql.log
查看配置方式:
mysql> show variables like '%log%error%';
mysql> show variables like '%log_error%';
+---------------------+--------------+
| Variable_name       | Value        |
+---------------------+--------------+
| binlog_error_action | IGNORE_ERROR |
| log_error           | ./web01.err  |
+---------------------+--------------+
2 rows in set (0.00 sec)
不進行設置,默認在上面的目錄 做用: 記錄mysql數據庫的通常狀態信息及報錯信息,是咱們對於數據庫常規報錯處理的經常使用日誌。

通常查詢日誌

配置方法:
[mysqld]
general_log=on
general_log_file=/data/mysql/server2.log
查看配置方式:
show variables like '%gen%';
做用:
記錄mysql全部執行成功的SQL語句信息,能夠作審計用,可是咱們不多開啓

3MySQL binlog介紹及管理實戰

 

1、二進制日誌都記錄了什麼?
  已提交的數據記錄,以event的形式記錄到二進制文件中
  只記錄增刪改
2、二進制記錄格式有哪些? row:行模式,即數據行的變化過程,上圖中Age=19修改爲Age=20的過程事件。
    行模式相比語句模式,臃腫,它要記錄每一行的變化 statement:語句模式,上圖中將update語句進行記錄。
    記錄函數類的操做,不是特別的準確,好比插入了一個時間函數now() mixed:以上二者的混合模式。
3、三種模式有什麼優缺點? 4、binlog的做用 備份恢復、複製
查看模式的設置
mysql> show variables like '%binlog_format%';
+---------------+-----------+
| Variable_name | Value     |
+---------------+-----------+
| binlog_format | STATEMENT |
+---------------+-----------+
1 row in set (0.00 sec)
二進制日誌是否開啓的查看
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | OFF   | 關閉的
+---------------+-------+
1 row in set (0.00 sec

二進制日誌管理

1、開啓二進制日誌
set sql_log_bin=0    在會話級別修改成臨時關閉
vi /etc/my.cnf
log-bin=/data/mysql/mysql-bin  在全局打開binlog

2、設置二進制日誌記錄格式(建議是ROW):
配置文件中修改:
binlog-format=ROW
命令行修改
mysql> SET GLOBAL binlog_format = 'STATEMENT';
mysql> SET GLOBAL binlog_format = 'ROW';
mysql> SET GLOBAL binlog_format = 'MIXED';    
3、查看binlog設置
show variables like '%binlog%';
+-----------------------------------------+----------------------+
| Variable_name                           | Value                |
+-----------------------------------------+----------------------+
| binlog_cache_size                       | 32768                |
| binlog_checksum                         | CRC32                |
| binlog_direct_non_transactional_updates | OFF                  |
| binlog_error_action                     | IGNORE_ERROR         |
| binlog_format                           | STATEMENT            |
| binlog_gtid_simple_recovery             | OFF                  |
| binlog_max_flush_queue_time             | 0                    |
| binlog_order_commits                    | ON                   |
| binlog_row_image                        | FULL                 |
| binlog_rows_query_log_events            | OFF                  |
| binlog_stmt_cache_size                  | 32768                |
| binlogging_impossible_mode              | IGNORE_ERROR         |
| innodb_api_enable_binlog                | OFF                  |
| innodb_locks_unsafe_for_binlog          | OFF                  |
| max_binlog_cache_size                   | 18446744073709547520 |
| max_binlog_size                         | 1073741824           |
| max_binlog_stmt_cache_size              | 18446744073709547520 |
| simplified_binlog_gtid_recovery         | OFF                  |
| sync_binlog                             | 0                    |何時寫入到磁盤上
  設置爲1 ,每次事務提交commit就binlog cache刷新,0就是達到內存大小才寫入

+-----------------------------------------+----------------------+
19 rows in set (0.00 sec)
設置文件中的內容
cat /etc/my.cnf
-------------------------------------------
[mysqld]
basedir=/appliacation/mysql
datadir=/application/mysql/data
soket=/appliacation/mysql/tmp/mysql.sock
port=3306
server_id=10
log-error=/var/log/mysql.log
log-bin=/application/mysql/data/mysql-bin
binlog_format=row
skip_name_resolve
innodb_data_file_path=ibdata1:76M;abdata2:50M:autoexend
default_storage_engine=innodb
character-set-server=utf8
antocommit=0
sync_binlog=1
[mysql]
socket=/application/mysql/tmp/mysql.sock
default-character-set=utf8
--------------------------------------------
查詢二進制日誌文件
ls -l /data/mysql/mysql-bin*
  或者在mysql中使用命令
mysql> SHOW BINARY LOGS;
+---------------+-----------+
| Log_name      | File_size |
+---------------+-----------+
| binlog.000015 |    724935 |
| binlog.000016 |    733481 |
查看當前在使用的binlog
mysql> SHOW MASTER STATUS;
+---------------+----------+--------------+------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------+----------+--------------+------------------+
| binlog.000016 |   733481 | world_innodb |     manual,mysql

刷新二進制日誌
    flush logs
截取二進制日誌
    mysqlbinlog --start-position=  --stop-position= >a.sql
刪除二進制:
默認狀況下,不會刪除舊的日誌文件。
根據存在時間刪除日誌:
SET GLOBAL expire_logs_days = 7;
…或者…
PURGE BINARY LOGS BEFORE now() - INTERVAL 3 day; 刪除3天以前的,手工
根據文件名刪除日誌:
PURGE BINARY LOGS TO 'mysql-bin.000010'; 刪除到那個文件
help purge binary logs 查看幫助
reset master 重第一個開始從新開始記錄,以前都刪除了

問題:
一、什麼是事件?
二、什麼是position?    

獲取二進制日誌的內容及事件,在一系列sql操做後,並commit後,能夠看到日誌內容

shell中使用mysqlbinlog /data/mysql/mysql-bin.000016
或者
sql中使用show binlog events in ‘mysql-bin.000016

可是看不到DML詳細的命令,能夠使用參數(mysqlbinlog --help|more)--base64-output=decode-rows 改變輸出

mysqlbinlog --base64-output=decode-rows -v /data/mysql/mysql-bin.000016

命令小結

show binary logs; 查詢二進制日誌文件
show binlog events in 'my-bin.000002'  查看日誌中的事件
show master status;  查看當前在使用的binlog

mysqlbinlog  --base64-output=decode-rows -v my-bin.000002  查看日誌轉碼後的 詳細結果,有DML語句的執行過程
mysqlbinlog --start-position=120 --stop-position=721   my-bin.000002  截取
mysqlbinlog --start-position=340 --stop-position=721   my-bin.000002 >/tmp/binlog.sql

 

二進制日誌管理實戰

1、經過截取binlog恢復損壞數據
  set sql_log_bin=0 臨時關閉二進制日誌記錄,不記錄恢復語句
  commit
  source //tmp/binlog.sql
二、若是咱們沒有提早去備份binlog,未來在誤操做以後,有如何恢復呢?
  去截取到誤操做以前的全部操做,沒有開始標記了
  mysqlbinlog --stop-position=721 my-bin.000002 >/tmp/binlog.sql
  
3、二進制日誌翻轉實現閃回數據(擴展)
   一年多的二進制文件,極大,極多,如何快速恢復
   

 

4MySQL 慢查詢日誌設置及管理實戰

慢查詢日誌
  是將mysql服務器中影響數據庫性能的相關SQL語句記錄到日誌文件
  經過對這些特殊的SQL語句分析,改進以達到提升數據庫性能的目的。
慢日誌設置
  long_query_time     : 設定慢查詢的閥值,超出次設定值的SQL即被記錄到慢查詢日誌,缺省值爲10s
  slow_query_log      : 指定是否開啓慢查詢日誌
  slow_query_log_file : 指定慢日誌文件存放位置,能夠爲空,系統會給一個缺省的文件host_name-slow.log
  min_examined_row_limit:查詢檢查返回少於該參數指定行的SQL不被記錄到慢查詢日誌
  log_queries_not_using_indexes: 不使用索引的慢查詢日誌是否記錄到索引
配置例子
  slow_query_log=1
  slow_query_log_file=/data/slow/slow.log (必需要有這個文件,且有權限
  long_query_time=0.5 (單位是s,)
  log_queries_not_using_indexes
  加入到/etc/my.cnf
  # min_examined_row_limit=100 (少於100行,認爲他沒問題,儘可能不用,若是查詢半小時,返回少於100)
mysql中查看配置
mysql> show variables like '%slow%';
+---------------------------+---------------------+
| Variable_name             | Value               |
+---------------------------+---------------------+
| log_slow_admin_statements | OFF                 |
| log_slow_slave_statements | OFF                 |
| slow_launch_time          | 2                   |
| slow_query_log            | ON                  |
| slow_query_log_file       | /data/slow/slow.log |
+---------------------------+---------------------+
5 rows in set (0.00 sec)
查看慢查詢超時時間
mysql> show variables like '%long_que%';
+-----------------+----------+
| Variable_name   | Value    |
+-----------------+----------+
| long_query_time | 0.500000 |
+-----------------+----------+
1 row in set (0.00 sec)
查看 不使用 索引 是否記錄的設置
mysql> show variables like '%indexes%';
+----------------------------------------+-------+
| Variable_name                          | Value |
+----------------------------------------+-------+
| log_queries_not_using_indexes          | ON    |
| log_throttle_queries_not_using_indexes | 0     |
+----------------------------------------+-------+
2 rows in set (0.00 sec)

 mysqldumpslow 如何處理慢日誌

記錄到慢日誌中的日誌是沒有順序的,它是追加的模式
mysqldumpslow命令
mysqldumpslow -s c -t 10 /data/slow/slow.log 次數
mysqldumpslow -s at -t 10 /data/slow/slow.log 時間
這會輸出記錄次數最多的10條SQL語句,其中:
-s   是表示按照何種方式排序,
  c、t、l、r分別是按照記錄次數、時間、查詢時間、返回的記錄數來排序,
  ac、at、al、
ar,表示相應的倒敘; -t 是top n的意思,即爲返回前面多少條的數據;
----擴展工具---
pt-query-diagest 自動作判斷,先優化哪個  percona-toolkit 裏面的
mysqlsla
重要的是先找到,哪條語句最慢,並且執行次數最多

十一、MySQL備份與恢復

理論狀況下,只要有二進制日誌文件在,我就能夠將數據庫恢復到任意時刻

可是,有一個前提,必須是全量

並且,二進制文件只適合短時間的恢復

1、備份的緣由

運維工做的核心簡單歸納就兩件事:

  • 第一個是保護公司的數據.
  • 第二個是讓網站能7*24小時提供服務(用戶體驗)。

2、備份的方式

備份的類型

  • 熱備份:在線備份,不影響業務正常運行,避開業務高峯
  • 冷備份:關閉數據,中止業務
  • 溫備份:加鎖備份,避開業務高峯

備份方式

邏輯備份(文本表示:SQL 語句)
(1)mysqldump---->建庫、建表、數據插入
(2)基於二進制日誌:數據庫的全部變化類的操做
(3)基於複製的備份:將二進制日誌實時傳送到另外一臺機器而且恢復
物理備份(數據文件的二進制副本)
(1)xtrabackup進行物理備份
(2)拷貝數據文件(冷備)
增量備份(刷新二進制日誌)
基於複製的備份

3、備份工具

一、mysqldump
    mysql原生自帶很好用的邏輯備份工具
二、mysqlbinlog
    實現binlog備份的原生態命令
三、xtrabackup
    precona公司開發的性能很高的物理備份工具

4mysqldump備份工具詳解

優勢:邏輯備份工具,都是SQL語句,都是文本格式,便於查看和編輯,更便於壓縮

缺點:備份效率

mysqldump經常使用參數 -u  -p  -h  -S  -P  首先是連接到數據庫
-A, --all-databases  全庫備份
  例子:mysqldump -uroot -p123 -A >/backup/full.sql
-B單庫備份
  -
例子:
   mysqldump -uroot -p123 -B lufei >/backup/lufei.sql
   mysqldump -uroot -p123  lufei >/backup/lufei1.sql
  - 區別:
  加-B,增長建庫(create)及「use庫」的語句,在未來恢復時,不須要手工進行建庫和use
  不加-B,須要恢復時,先建立庫,use到庫下再進行恢復
  - 另外,-B選項還能夠實現,同時備份多個庫,備份到同一個文件中
  mysqldump -uroot -p123 -B lufei oldboy>/backup/lufei_oldboy.sql
  不加-B,去備份,他的功能是備份路飛數據庫下的oldboy表
  mysqldump -uroot -p123  lufei oldboy>/backup/lufei_oldboy.sql
  mysqldump 庫1 表1 表2 表3 >庫1.sql
生產環境下,也要加的額外參數
-R, --routines 備份存儲過程和函數數據 --triggers 備份觸發器數據
mysqldump -uroot -p123 -A  -R --triggers >/backup/full.sql 備份多個表: mysqldump 庫1 表1 表2 表3
>庫1.sql mysqldump 庫2 表1 表2 表3 >庫2.sql -F, --flush-logs 備份時刷新binlog日誌(回顧binlog),爲了方便未來二進制截取時的起點   天天晚上0點備份數據庫   mysqldump -A -B -F >/opt/$(date +%F).sql
  提示:每一個庫都會刷新一次.
  即,-F會根據有多少個庫,刷新出多少個二進制文件   [root@db02
~]# ll /application/mysql/logs/   -rw-rw---- 1 mysql mysql 168 Jun 21 12:06 oldboy-bin.000001   -rw-rw---- 1 mysql mysql 168 Jun 21 12:06 oldboy-bin.000002   -rw-rw---- 1 mysql mysql 210 Jun 21 12:07 oldboy-bin.index
一個解決每一個庫都會刷新的參數
--master-data={1|2} 告訴你備份時刻的binlog位置,通常咱們選擇使用2,以註釋的方式記錄二進制日誌位置   2 註釋   1 非註釋,要執行(主從複製)   mysqldump -uroot -p123 -A --master-data=2 >/backup/full.sql
  看一下記錄: [root@db02 logs]#
sed -n '22p' /opt/t.sql -- CHANGE MASTER TO MASTER_LOG_FILE='oldboy-bin.000005', MASTER_LOG_POS=344; [root@db02 logs]# mysqldump -B --master-data=2 oldboy >/opt/t.sql 鎖表:適合全部引擎(myisam,innodb) (溫備份) -x, --lock-all-tables -l, --lock-tables mysqldump -B -x oldboy >/opt/t.sql   有了--master-data不用鎖表參數了 基於事務引擎:不用鎖表就能夠得到一致性的備份. 生產中99% 使用innodb事務引擎. ACID四大特性中的隔離性 --single-transaction 對innodb引擎進行熱備
mysqldump -uroot -p123 -A -R --triggers --master-data=2 --single-transaction >/backup/full.sql
這是比較合適的備份方式
熱備,就是不須要鎖表,它是以快照的方式實現熱備 舉例子:查人數,把教室的學員照個相,在相片上點數 壓縮備份:壓縮比很高 mysqldump
-B --master-data=2 oldboy|gzip >/opt/t.sql.gz 解壓: zcat t.sql.gz >t1.sql gzip -d t.sql.gz #刪壓縮包 適合多引擎混合(例如:myisam與innodb混合)的備份命令以下: mysqldump -A -R --triggers --master-data=2 --single-transaction |gzip >/opt/all_$(date +%F).sql.gz

使用source命令進行恢復:
mysql>set sql_log_bin=0; 臨時不向二進制文件記錄
mysql> source /opt/xxx.sql;

5mysqldump+mysqlbinlog實現增量備份

 

6、企業級備份策略及恢復案例

背景環境:
    正在運行的網站系統,mysql數據庫,數據量25G,日業務增量10-15M。
備份方式:
    天天23:00點,計劃任務調用mysqldump執行全備腳本
故障時間點:
    上午10點,誤刪除了一個表

如何恢復?
思路:
    1、斷開業務,防止對數據庫二次傷害,掛出維護頁面
    2、搭建備用庫,恢復全備
    3、截取昨天晚上23:00以後到上午10點誤刪除操做以前的二進制日誌
    4、恢復到備用庫,驗證數據可用性和完整性
    5、兩種方案恢復前端應用
        5.1 備用庫導出誤刪除的表,導入到生產庫,開啓業務
        5.2 直接將應用切割到備用庫,替代生產庫,開啓業務
------------------
模擬故障並恢復:
0、爲了模擬 二進制全清除,
mysql>reset master;
  刪除原庫數據
cd /application/mysql/data
\rm -rf *
pkill mysqld
  初始化
/application/mysql/script/mysql_install_db --basedir=/application/mysql --datadir=/application/data --user=mysql
  啓動
/etc/init.d/mysqld start
mysql
1、插入原始數據: mysql> create database oldboy; mysql> use oldboy mysql> create table t1 (id int,name varchar(20)); mysql> insert into t1 values (1,'zhang3'); mysql> insert into t1 values (2,'li4'); mysql> insert into t1 values (3,'wang5'); mysql> commit; 2、模擬前一天晚上23:00全備 mysqldump -A -R --triggers --master-data=2 --single-transaction |gzip >/backup/all_$(date +%F).sql.gz 3、模擬白天(23:00-10:00)業務對數據的修改 mysql> insert into t1 values (4,'zhang33'); mysql> insert into t1 values (5,'li44'); mysql> insert into t1 values (6'wang54'); mysql> commit; 4、模擬故障 drop table t1; 5、恢復 (1)準備全備,並獲取到備份文件中的binlog的截取起點 gunzip all_2018-04-04.sql.gz -- CHANGE MASTER TO MASTER_LOG_FILE='my-bin.000004', MASTER_LOG_POS=731; (2)截取二進制日誌
  查看刪庫前的日誌
  mysql>show binlog events in 'my-bin.000004',找到刪除以前的位置
mysqlbinlog
--start-position=731 --stop-position=1126 /data/binlog/my-bin.000004 >/backup/binlog.sql ----- show binlog events in 'my-bin.000004'; ----》drop以前的position爲1126 ----- (3)恢復全備+binlog set sql_log_Bin=0; source /backup/all_2018-04-04.sql; source /backup/binlog.sql

7Xtrabackup備份恢復實戰

Xtrabackup介紹

percona公司的備份工具,性能比較高。物理備份工具。
特色:
物理備份工具,在同級數據量基礎上,都要比邏輯備份性能要好的多。
特別是在數據量比較大的時候,體現的更加明顯。
備份方式:
    1、拷貝數據文件
    2、拷貝數據頁
備份原理(innodb):
    1、對於innodb表,能夠實現熱備
        (1)在數據還有修改操做的時刻,直接將數據文件中的數據頁備份
          此時,備份走的數據對於當前mysql來說是不一致。
        (2)將備份過程當中的redo和undo一併備走。
        (3)爲了恢復的時候,只要保證備份出來的數據頁LSN 能和redo LSN匹配,
            未來恢復的就是一致的數據。redo應用和undo的應用。
    2、對與myisam表,實現自動鎖表拷貝文件。

Xtrabackup安裝

1、安裝
wget -O /etc/yum.repos.d/epel.repo  http://mirrors.aliyun.com/repo/epel-6.repo
yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL

wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.4/binary/redhat/6/x86_64/percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm
yum -y install percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm

備份命令:
xtrabackup
innobackupex ******
依賴配置文件,須要配置好

Xtrabackup全備份及恢復實戰

建立備份目錄
mkdir /server/backup -p
全備完整命令 innobackupex
--user=root --password=oldboy123
--socket=/application/mysql-5.6.34/tmp/mysql.sock
--no-timestamp /server/backup/full

由於是新庫,且配置文件中指定可sock簡單的命令
innobackupex  /server/backup/
默認是備份到以時間戳做爲目錄名的目錄中,加參數後,備份到指定目錄
innobackupex     --no-timestamp  /server/backup/full

全備的回覆例子: 一、恢復數據前的準備(合併xtabackup_log_file和備份的物理文件),由於備份時把redo和undo也備走了
-use-memory:恢復的時候,單獨指定一個內存,屬於優化的細節
--apply-log:作操做-->恢復數據前的準備(合併xtabackup_log_file和備份的物理文件) innobackupex
--apply-log --use-memory=32M /server/backup/full/
二、模擬故障
停庫: Kill
-9 pid lsof -i :3306 破壞數據: cd /application/mysql/data mv data /opt/ 或者 \rm -rf *
三、恢復 cp -a /server/backup/full/ /application/mysql/data
或者
innobackupex --copy-back /server/backup/full/
注意:恢復時,要確認數據路徑是空的,而且數據庫是停掉的
chown -R mysql.mysql /application/mysql/data 啓動: /etc/init.d/mysqld start mysql -e "select * from oldboy.test" 注:咱們還能夠使用—copy-back參數進行恢復

Xtrabackup實現增量備份與恢復實戰

1、全備:
innobackupex --user=root --password=123 --no-timestamp /backup/full/
2、模擬數據變化
3、第一增量:
innobackupex --user=root --password=123 --incremental --no-timestamp --incremental-basedir=/backup/full/ /backup/inc1
4、模擬數據變化
5、第二次增量:
innobackupex --user=root --password=123 --incremental --no-timestamp --incremental-basedir=/backup/inc1 /backup/inc2
6、模擬數據損壞
7、恢復數據:
innobackupex --apply-log --redo-only /backup/full
沒法直接恢復,要依賴全備,合併 innobackupex
--apply-log --redo-only --incremental-dir=/backup/inc1 /backup/full innobackupex --apply-log --incremental-dir=/backup/inc2 /backup/full innobackupex --apply-log /backup/full
--redo-only:只把已提交的事務合併,不合並undo。除了最後一次增量,都要加上這個參數
把原有的數據刪掉,必須是空的
cd /application/mysql/data
\rm -rf *

停庫
pkill mysqld
innobackupex --copy-back /backup/full/

Xtrabackup企業級增量備份實戰

背景:
某大型網站,mysql數據庫,數據量500G,每日更新量100M-200M
備份策略:
xtrabackup,每週日0:00進行全備,週一到週六00:00進行增量備份。
故障場景:
週三上午10點出現數據庫意外刪除表操做。
如何恢復?
思路:
    一、停業務,掛維護頁
    二、找備用庫
    三、合併full+inc1+inc2
    四、截取週二晚上inc2備份後到週三上午10點,t1表刪除以前的binlog日誌
    五、將合併後的full+截取的binlog恢復到備用庫
    六、驗證數據可用性和完整性
    七、使用備用庫替代生產庫使用 或者 將t1表導出並導入回生產庫
    八、業務恢復

-----------------
-----------------
思考:以上恢復策略是否能夠優化?
爲了恢復1G表,須要將整個全備恢復,有必要嗎?有什麼好的解決辦法?

drop table t1;
create table t1 (id int,name varchar(20)); 建立表結構,和原來的表結構如出一轍
alter table t1 discard tablespace; 在數據庫內部刪除

cd /application/mysql/data/oldboy
cp /backup/full/oldboy/t1.ibd  ./ 將備份中的.ibd文件拷貝到新建的表下面

chown  -R mysql.mysql * 修改文件的權限歸屬
alter table t1 import tablespace; 導入數據

十二、MySQL主從複製

1、主從複製簡介

複製能爲咱們作什麼?

  1. 輔助備份
  2. 高可用
  3. 分擔負載

複製是 MySQL 的一項功能,容許服務器將更改從一個實例複製到另外一個實例。
    - 主服務器將全部數據和結構更改記錄到二進制日誌中。
    - 從屬服務器從主服務器請求該二進制日誌並在本地應用其內容。

2、主從複製原理

 

主從複製的前提

1.1 兩臺以上mysql實例 多臺物理機 多個mysql實例 1.2 主庫要開啓二進制日誌 1.3 主庫要提供複製相關的用戶 replication slave,一個比較特殊的權限 grant replication slave on *.* to repl@'10.0.0.%' identified by '123'; 1.4 從庫須要將和主庫相差的數據,進行追加 通常狀況下能夠人爲備份主庫數據,恢復到從庫上 1.5 從應該從恢復以後的時間點,開始自動從主庫獲取新的二進制日誌開始應用 咱們須要人爲告訴從庫,從哪開始自動開始複製二進制日誌(file+position),另外還須要告訴從庫user,passwd,port,ip change master to 命令根據mster.info中的參數 來鏈接主庫

複製中的線程

1、主庫
  Dump thread:在複製過程當中,主庫發送二進制日誌的線程
2、從庫
  IO thread:向主庫請求二進制日誌,而且接受二進制日誌的線程
  SQL thread:執行請求過來的二進制線程

複製中的文件

1、主庫
  binlog:主庫的二進制文件
2、從庫
  Relay-log:中繼日誌,存儲請求過來的二進制日誌
  Relay-index:
  Master.info:
    一、從庫鏈接主庫的重要參數(user,passwd,ip,port)  
    二、上次獲取過的主庫二進制日誌的位置
  Relay-log.info:存儲從庫SQL線程已經執行過的relaylog日誌位置

主從複製的工做原理

3.1 從庫,IO線程,讀取master.info中的信息,
    獲取到鏈接參數(user\passwd\ip\port)+上次請求過的主庫的binlog的位置(例子:mysql-bin.000003,position=640)
3.2 IO線程使用連接到主庫,拿着位置信息(mysql-bin.000003,position=640),問主庫有沒有比這個更新的二進制日誌。
3.3 主庫查詢二進制日誌,並對比從庫發送過來的位置信息(mysql-bin.000003,position=640),若是有新的二進制日誌,會經過
    dump thread發送給從庫。
3.4 從庫經過IO線程,接受主庫發來的二進制日誌,存儲到TCP/IP緩存中,而且返回「ACK」確認給主庫,這時主庫收到ACK後,
    就認爲複製完成了,能夠繼續其餘工做了。
3.5 從庫更新master.info,二進制日誌位置更新爲新的位置信息。
3.6 從庫IO線程會將TCP/IP緩存中的日誌,存儲到relay-log中繼日誌文件中。
3.7 從庫SQL線程,讀取relay-log.info,獲取到上次執行到的relaylog日誌位置,以這個位置信息做爲起點,日後繼續執行中繼日誌。
3.8 SQL線程執行完成全部relay以後,會更新relay-log.info信息爲新位置信息。

到此爲止,一次完整的複製過程就完成了。

3、主從複製搭建實踐

思路:
1、兩個節點
2、主庫binlog開啓,從庫開啓relay-log
3、server-id不一樣
4、主庫建立複製帳戶
5、主庫備份並記錄二進制文件和position
6、從庫change master to鏈接主庫
7、啓動從庫複製
8、驗證主從
詳細配置過程,請看配置文檔。

配置步驟

主從複製搭建實戰:

1、準備環境
思路:
1、兩個以上節點(多實例)
3307:master
3308:slave1
3309:slave2
2、主庫binlog開啓,從庫開啓relay-log(默認在數據目錄下生成)
vim /data/3307/my.cnf
log-bin=/data/3307/mysql-bin
binlog_format=row

3、server-id不一樣
[root@db02 data]# cat /data/3307/my.cnf |grep server-id
server-id=3307
[root@db02 data]# cat /data/3308/my.cnf |grep server-id
server-id=3308
[root@db02 data]# cat /data/3309/my.cnf |grep server-id
server-id=3309
4、關閉數據庫的自動域名解析
每一個節點都加入如下配置:vim /data/3307{8|9}/my.cnf
skip-name-resolve
5、啓動多實例
mysqld_safe --defaults-file=/data/3307/my.cnf &
mysqld_safe --defaults-file=/data/3308/my.cnf &
mysqld_safe --defaults-file=/data/3309/my.cnf &

6、主庫建立複製帳戶
鏈接到主庫:
mysql -S /data/3307/mysql.sock
grant replication slave on *.* to repl@'10.0.0.%' identified by '123';

7、從庫數據的追加
    (1)不須要追加的狀況
     主和從同時搭建的新環境,就不須要備份主庫數據,恢復到從庫了,直接從第一個binlog(mysql-bin.000001)的開頭位置(120)
    (2)若是主庫已經工做了很長時間了,咱們通常須要備份主庫數據,恢復到從庫,而後從庫從備份的時間點起自動進行復制
重點針對第二種狀況進行演示:
備份主庫:
mysqldump -S /data/3307/mysql.sock -A -R  --triggers --master-data=2 --single-transaction >/tmp/full.sql
sed -n '22p' /tmp/full.sql  下面須要用到這個信息
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=325
恢復到從庫:
mysql -S /data/3308/mysql.sock 
mysql> set sql_log_bin=0;
mysql> source /tmp/full.sql

8、從庫開啓主從複製:
mysql -S /data/3308/mysql.sock

help change master to
執行命令:
CHANGE MASTER TO
  MASTER_HOST='10.0.0.52',
  MASTER_USER='repl',
  MASTER_PASSWORD='123',
  MASTER_PORT=3307,
  MASTER_LOG_FILE='mysql-bin.000002',
  MASTER_LOG_POS=325;
  
開啓主從(開啓IO和SQL線程):
start slave;

9、查看主從狀態:

show slave status\G

Slave_IO_Running: Yes
Slave_SQL_Running: Yes
--------------
10、主從重要狀態信息介紹

show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Last_IO_Errno: 0
Last_IO_Error: 
Last_SQL_Errno: 0
Last_SQL_Error: 

4、主從複製狀態監控

mysql> show slave status\G
***************** 1. row *********************
       Slave_IO_State: Queueing master event to the relay log
                    ...
      Master_Log_File: mysql-bin.005
  Read_Master_Log_Pos: 79
       Relay_Log_File: slave-relay-bin.005
        Relay_Log_Pos: 548
Relay_Master_Log_File: mysql-bin.004 Slave_IO_Running: Yes 主要看這兩 Slave_SQL_Running: Yes 主要看這兩
                    ...
  Exec_Master_Log_Pos: 3769
                    ... 
Seconds_Behind_Master: 8

5、主從複製基本故障處理

主從複製故障及解決
    stop slave; #<==臨時中止同步開關。
    set global sql_slave_skip_counter = 1 ; #<==將同步指針向下移動一個,若是屢次不一樣步,能夠重複操做。
    start slave;
    /etc/my.cnf
    slave-skip-errors = 1032,1062,1007
    如何避免:從庫只讀 read_only

IO線程故障:
    一、主庫鏈接不上
       user、password、port、ip 錯誤
         解決方案:
            stop  slave;
            reset slave all;  清理master.info。從新開始
            change master to    
            start slave;
      防火牆
      網絡不通
       skip-name-resolve
       stop  slave;
       start slave;
       
    二、主庫二進制日誌丟失或損壞
        解決方案:
          stop  slave;    
          reset slave all;  
          從新備份恢復
          change master to    
          start slave;
SQL線程故障
查看狀態,發現SQL線程被關閉,且出現下面的問題
   執行relaylog日誌新事件
    一、刪除、修改對象的操做時,沒有這個對象
    二、建立對象時,對象已存在
    三、主鍵衝突
從庫作寫入操做,會致使以上問題出現

處理方法:
stop slave;
set global sql_slave_skip_counter = 1; 跳過錯誤
start slave;

/etc/my.cnf
slave-skip-errors = 1032,1062,1007 跳過指定代號表明的錯誤

可是,以上操做有時是有風險的,最安全的作法就是從新構建主從。
怎麼預防以上問題?
從庫加入配置文件
  設置成只讀庫
set global read_only=1;
vim /etc/my.cnf
read_only=1           ---->只能控制普通用戶,控制不了管理員,從庫設置成只讀庫
------------------
主從異常——主從延時過長
show slave status \G 查看狀態
Seconds_Behind_Master:0 主從延時爲0

默認的主從複製機制是異步的一個過程。

主庫緣由:
一、主庫作修改操做以後,纔會記錄二進制日誌。
sync_binlog=0/1
官方文檔
If the value of this variable is greater than 0,
the MySQL server synchronizes its binary log to disk (using fdatasync())
after sync_binlog commit groups are written to the binary log.
The default value of sync_binlog is 0, which does no synchronizing to disk—in this case,
the server relies on the operating system to flush the binary log's contents from time to time as for any other file.
A value of 1 is the safest choice because in the event of a crash you lose at most one commit group from the binary log.
However, it is also the slowest choice (unless the disk has a battery-backed cache, which makes synchronization very fast)
---------------------總結成兩句話
    1:表示:每次事務commit,刷新binlog到磁盤
    0:系統決定binlog什時候刷新到磁盤
二、主庫的壓力特別大(大事務、多事務)
三、從庫數量多,致使dump線程繁忙
-------------------
從庫緣由:
一、relay-log寫入慢
二、SQL線程慢(主從硬件差別比較大)
-----------------------------
儘量的避免主從延時
一、sync_binlog=1
二、大事務拆成小事務,多事務進行分離
三、使用多級主從,分庫分表架構
四、將binlog放到ssd或者flash上,高性能存儲

五、將relay放到ssd或者flash上
六、儘可能選擇和主庫一致硬件和配置

6、主從複製高級功能

1、延時複製
2、SQL多線程
3、複製過濾
4、半同步複製
5、GTID複製

 詳細

- 主從複製高級功能——半同步複製
出發點:保證主從數據一致性的問題,安全的考慮
5.5出現的概念,可是不建議使用,性能太差,和以前不一樣的是ack返回的時間點晚了一步,必須在二進制文件寫入relay5.6之後出現group commit 組提交功能,來提高開啓版同步複製的性能

5.7加強半同步複製的新特性:after sync;

------
加載插件
主:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
從:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
查看是否加載成功:
show plugins;

啓動:
主:
SET GLOBAL rpl_semi_sync_master_enabled = 1;
從:
SET GLOBAL rpl_semi_sync_slave_enabled = 1;

重啓從庫上的IO線程
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;

查看是否在運行
主:
show status like 'Rpl_semi_sync_master_status';
從:
show status like 'Rpl_semi_sync_slave_status';
-----

補充:
rpl_semi_sync_master_timeout     | 10000
默認狀況,到達10秒鐘尚未ack,主從關係自動切換爲普通複製
若是是1主多從的半同步複製,只要有一臺落地relaylog,返回ack,此次半同步就完成了。

--------------------------------------
- 主從複製高級功能——延時從庫 會專門找一個節點,配置成延時節點,儘量防止邏輯損壞,通常狀況下這個節點會被用備份 咱們配置的是SQL_thread的延時,通常會設置到3-6小時 mysql>stop slave; mysql>CHANGE MASTER TO MASTER_DELAY = 60; mysql>start slave; mysql> show slave status \G SQL_Delay: 300 取消延時: mysql> stop slave; mysql> CHANGE MASTER TO MASTER_DELAY = 0; mysql> start slave; -----------------------
- 主從複製高級功能——複製過濾
  挑着複製,只想複製某些內容
主庫方面控制(不建議使用):有分風險
show master status; 白名單:只記錄白名單中列出的庫的二進制日誌 binlog
-do-db 黑名單:不記錄黑名單列出的庫的二進制日誌 binlog-ignore-db 從庫方面控制:
show slave status\G 查看信息   白名單:只執行白名單中列出的庫或者表的中繼日誌
--replicate-do-db=test 庫 --replicate-do-table=test.t1 庫下的表 --replicate-wild-do-table=test.x* 模糊   黑名單:不執行黑名單中列出的庫或者表的中繼日誌 --replicate-ignore-db --replicate-ignore-table --replicate-wild-ignore-table 只複製world數據庫的數據
  主:只記錄world的二進制日誌,可是風險大
  從:寫入配置文件/data/3308/my.cnf
    replicate-do-db=world
--------------
主從複製新特性——GTID複製 以前說的是基於 二進制日誌的文件號 + 二進制日誌position號 來實現的複製
叫作傳統複製結構classic

GTID 是新的複製結構
  好處:簡化了複製的難度,主從切換的時候更有優點

5.6新特性 GTID(Global Transaction ID全局事務ID)是對於一個已提交事務的編號,而且是一個全局惟一的編號。 它的官方定義以下: GTID = source_id :transaction_id 7E11FA47-31CA-19E1-9E56-C43AA21293967:29 每一臺mysql實例中,都會有一個惟一的uuid(128位隨機數),標識實例的惟一性 auto.cnf,存放在數據目錄下 重要參數: gtid-mode=on enforce-gtid-consistency=true log-slave-updates=1 gtid-mode=on --啓用gtid類型,不然就是普通的複製架構 enforce-gtid-consistency=true --強制GTID的一致性 log-slave-updates=1 --slave更新是否記入日誌 -----------------

構建1主2從的GTID複製環境: 3臺虛擬機, db02 克隆兩臺虛擬機環境,分別命名爲db0一、db03,在生產中準備3臺真實的物理機,不用多實例 要求: 1、IP地址、主機名 db01:10.0.0.51/24 db03:10.0.0.53/24 2、清理全部以前3306的相關數據,只留軟件 db01: cd /application/mysql/data/ \rm -rf * cd /data/binlog/ \rm -rf * db02: cd /application/mysql/data/ \rm -rf * cd /data/binlog/ \rm -rf * db03: cd /application/mysql/data/ \rm -rf * cd /data/binlog/ \rm -rf * 3、準備配置文件 規劃: 主庫: 10.0.0.51/24 從庫1: 10.0.0.52/24 從庫2:10.0.0.53/24 主庫: 加入如下配置信息 db01:10.0.0.51/24 vim /etc/my.cnf [mysqld] basedir=/application/mysql datadir=/application/mysql/data socket=/tmp/mysql.sock log-error=/var/log/mysql.log log_bin=/data/binlog/mysql-bin binlog_format=row skip-name-resolve server-id=51 gtid-mode=on enforce-gtid-consistency=true log-slave-updates=1 [client] socket=/tmp/mysql.sock slave1: db02:10.0.0.52/24 vim /etc/my.cnf [mysqld] basedir=/application/mysql datadir=/application/mysql/data socket=/tmp/mysql.sock log-error=/var/log/mysql.log log_bin=/data/binlog/mysql-bin binlog_format=row skip-name-resolve server-id=52 gtid-mode=on enforce-gtid-consistency=true log-slave-updates=1 [client] socket=/tmp/mysql.sock slave2: db02:10.0.0.53/24 vim /etc/my.cnf [mysqld] basedir=/application/mysql datadir=/application/mysql/data socket=/tmp/mysql.sock log-error=/var/log/mysql.log log_bin=/data/binlog/mysql-bin binlog_format=row skip-name-resolve server-id=53 gtid-mode=on enforce-gtid-consistency=true log-slave-updates=1 [client] socket=/tmp/mysql.sock -----------------
三臺節點分別初始化數據: /application/mysql/scripts/mysql_install_db --user=mysql --basedir=/application/mysql --datadir=/application/mysql/data/ 分別啓動三個節點mysql: /etc/init.d/mysqld start 測試啓動狀況: mysql -e "show variables like 'server_id'" master:51 slave:52,53 51: grant replication slave on *.* to repl@'10.0.0.%' identified by '123'; 52\53: change master to master_host='10.0.0.51',master_user='repl',master_password='123' ,MASTER_AUTO_POSITION=1;
# 參數MASTER_AUTO_POSITION=1 自動判斷哪些事務有,哪些食物沒有,不用像以前那樣設置起點位置 start slave;
-------------
show master status \G
show slave status \G 查看狀態
正常狀況Retrieved_Gtid_Set(記錄的事務數) 和 Executed_gtid_Set(已執行的事務數) 的事務數是同樣的
除了這兩個標識,其餘的變化不大

 1三、MHA高可用

普通主從複製方案不足

高可用---業務不間斷的工做---用戶的體驗
普通主從環境,存在的問題:
1、監控的問題:APP應用程序,並不具有監控數據庫的功能,沒有責任監控數據庫是否能鏈接。 2、選主的問題:選替代者,沒有選主的功能 3、failover:VIP漂移,將IP落到新的主上,對於應用透明 4、數據補償:數據不全

 宕機後的架構形態的改變

普通主從複製架構思路主庫宕機場景(1

普通主從複製架構思路主庫宕機場景(2

普通主從複製架構思路主庫宕機場景(3

高可用解決方案簡介

企業高可用解決方案:
MMM(過期)
MHA(目前推薦)
PXC、Galera Cluster(出現不少年,企業不多用)
5.7.17 MGR 、Innodb Cluster(將來的趨勢,儘早研究)
MySQL NDB Cluster(出現不少年,仍然不完善)
MyCAT 高可

MHA簡介

MHA(Master High Availability),
由日本DeNA公司youshimaton(現就任於Facebook公司)開發。
MHA能作到在10~30秒以內自動完成數據庫的Failover,
Failover的過程當中,能最大程度上保證數據的一致性。 該軟件由兩部分組成:MHA Manager(管理節點)和MHA Node(數據節點)。 半同步複製,能夠大大下降數據丟失的風險。MHA能夠與半同步複製結合起來。 MHA高可用集羣,要求一個複製集羣中須要有三臺數據庫服務器,一主二從,不支持多實例。
出於機器成本的考慮,淘寶也在該基礎上進行了改造,淘寶TMHA支持一主一從。 注意:必須使用獨立的數據庫節點,不支持多實例。

 Manager工具包主要包括如下幾個工具:


masterha_check_ssh        檢查MHA的SSH配置情況
masterha_check_repl       檢查MySQL複製情況
masterha_manger           啓動MHA
masterha_check_status     檢測當前MHA運行狀態
masterha_master_monitor 檢測master是否宕機
masterha_conf_host         添加或刪除配置的server信息
masterha_master_switch     控制故障轉移(自動或者手動)

 Node工具包

Node工具包(這些工具一般由MHA Manager的腳本觸發,無需人爲操做)主要包括如下幾個工具:
save_binary_logs             
  保存和複製master的二進制日誌 
apply_diff_relay_logs         
  識別差別的中繼日誌事件並將其差別的事件應用於其餘的從節點
slave filter_mysqlbinlog     
  去除沒必要要的ROLLBACK事件(MHA已再也不使用這個工具) 
purge_relay_logs             
  清除中繼日誌(不會阻塞SQL線程)

 MHA實現原理

1)Manager程序負責監控全部已知Node(1主2從全部節點)
(2)當主庫發生意外宕機
    (2.1)mysql實例故障(SSH可以鏈接到主機)
           0、監控到主庫宕機,選擇一個新主(取消從庫角色,reset slave),選擇標準:數據較新的從庫會被選擇爲新主(show slave status\G)
           1、從庫經過MHA自帶腳本程序,當即保存缺失部分的binlog
           2、二號從庫會從新與新主構建主從關係,繼續提供服務
           3、若是VIP機制,將vip從原主庫漂移到新主,讓應用程序無感知
    (2.2)主節點服務器宕機(SSH已經鏈接不上了)
           0、監控到主庫宕機,嘗試SSH鏈接,嘗試失敗
           1、選擇一個數據較新的從庫成爲新主庫(取消從庫角色 reset slave),判斷細節:show slave status\G
           2、計算從庫之間的relay-log的差別,補償到2號從庫
           3、二號從庫會從新與新主構建主從關係,繼續提供服務
           4、若是VIP機制,將vip從原主庫漂移到新主,讓應用程序無感知
           5、若是有binlog server機制,會繼續講binlog server中的記錄的缺失部分的事務,補償到新的主庫

 

部署步驟

  1. 三臺MySQL獨立節點實例,主機名、IP、防火牆關閉等
  2. 開啓1主2從GTID複製結構--以前作過了
  3. 關閉各節點relay-log自動刪除功能
    1. relay_log_purge=0
    2. 記不住show一下:show variables like '%relay%';
  4. 各節點部署node工具包及依賴包
  5. 選擇其中一個從節點進行部署manager工具包
  6. 各節點ssh祕鑰互信配置
  7. 配置manager節點配置文件(注意:在數據庫中添加mha管理用戶和密碼)
  8. 作ssh互信檢查和主從狀態檢查
  9. 開啓MHA功能

MHA高可用解決方案詳解

3.1、安裝mha node:

依賴包perl-DBD-MySQL ,並在三個節點都安裝node軟件
rpm包直接
rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm

3.2、主庫中建立mha管理用戶
grant all privileges on *.* to mha@'10.0.0.%' identified by 'mha';                    
從庫中也要查看是否是有這個帳戶                    
3.3、配置軟鏈接

ln -s /application/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog
ln -s /application/mysql/bin/mysql /usr/bin/mysql

3.4、部署manger節點(建議在從節點db03)
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes

3.5、安裝  manager軟件
rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm 

3.6、建立Manager必須目錄與配置文件
mkdir -p /etc/mha
mkdir -p /var/log/mha/app1    ----》能夠管理多套主從複製
建立配置文件 (不須要的配置不要留着,註釋沒用,切換後會重寫)
vim /etc/mha/app1.cnf     -----》serverdefault能夠獨立
[server default]                        
manager_log=/var/log/mha/app1/manager
manager_workdir=/var/log/mha/app1
master_binlog_dir=/data/binlog
user=mha
password=mha
ping_interval=2
repl_password=123
repl_user=repl
ssh_user=root

[server1]
hostname=10.0.0.51
port=3306

[server2]
hostname=10.0.0.52
port=3306

[server3]
hostname=10.0.0.53
port=3306

3.7、配置互信(全部節點)
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa >/dev/null 2>&1

ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.0.0.51
ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.0.0.52
ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.0.0.53

檢測是否成功
ssh 10.0.0.{51..53} date 3.8、檢測互信 masterha_check_ssh --conf=/etc/mha/app1.cnf 3.9、檢測主從 masterha_check_repl --conf=/etc/mha/app1.cnf 3.10、啓動MHA manager nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &

查看日誌,
cd /var/log/mha
cd app1/
tail -f manager

故障演練

1、宕掉db01主庫,停掉數據庫
2tail -f /var/log/mha/app1/manager  觀察日誌變化
3、恢復主庫運行,從新將db01加入到主從複製關係中
mysql CHANGE MASTER TO MASTER_HOST
='10.0.0.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123'; start slave;
4、將配置文件中加入修稿的故障節點(由於立即後,系統會自動清理掉server1) 5、啓動MHA了manager程序 masterha_check_ssh --conf=/etc/mha/app1.cnf masterha_check_repl --conf=/etc/mha/app1.cnf nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &

檢測狀態
masterha_check_status --conf=/etc/mha/app1.cnf

使用MHA自帶腳本實現IP FailOver(vip 漂移,應用透明)

配置步驟
上傳準備好的/usr/local/bin/master_ip_failover

vim master_ip_failover
只修改腳本中如下內容
my $vip = '10.0.0.55/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
給腳本添加 執行權限
chown +x
轉換格式
dos2unix /usr/local/bin/master_ip_failover

修改配置文件 vim
/etc/mha/app1.cnf 添加: master_ip_failover_script=/usr/local/bin/master_ip_failover 重啓mha masterha_stop --conf=/etc/mha/app1.cnf nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 & 手工在主庫上綁定vip,注意必定要和配置文件中的ethN一致,個人是eth0:1(1是key指定的值) ifconfig eth0:1 10.0.0.55/24 切換測試: 停主庫,看vip是否漂移

binlogserver配置:

思考:爲何不直接在從slave上左binlogserver?

找一臺額外的機器,必需要有5.6以上的版本,支持gtid並開啓,咱們直接用的第二個slave

[binlog1]
no_master=1    不參與主從
hostname=10.0.0.53
master_binlog_dir=/data/mysql/binlog  單獨的,不能和主庫的binlog同樣
提早建立好,這個目錄不能和原有的binlog一致
mkdir -p /data/mysql/binlog
chown -R mysql.mysql /data/mysql/*
修改完成後,將主庫binlog拉過來(從000001開始拉,以後的binlog會自動按順序過來) cd /data/mysql/binlog -----》必須進入到本身建立好的目錄 mysqlbinlog -R --host=10.0.0.51 --user=mha --password=mha --raw --stop-never mysql-bin.000001 & 最好,先在主庫查看一下,是否是從000001開始的
重啓MHA,生效配置: 重啓mha masterha_stop --conf=/etc/mha/app1.cnf nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &

其餘參數說明

manager檢測節點存活的間隔時間,總共會探測4次。
ping_interval=2
#節點標籤下設置
設置爲候選master,若是設置該參數之後,發生主從切換之後將會將此從庫提高爲主庫,即便這個主庫不是集羣中事件最新的slave candidate_master
=1
#默認狀況下若是一個slave落後master 100M的relay logs的話,MHA將不會選擇該slave做爲一個新的master, 由於對於這個slave的恢復須要花費很長時間,
經過設置check_repl_delay
=0, MHA觸發切換在選擇一個新的master的時候將會忽略複製延時,這個參數對於設置了candidate_master=1的主機很是有用, 由於這個候選主在切換的過程當中必定是新的master check_repl_delay=0

14 、Atlas-MySQL讀寫分離架構

MHA高可用架構的問題

  • 全部的壓力都集中在了主上
  • 從的資源被大大的浪費,應該想辦法讓從分擔一下主的壓力

咱們的業務基本都是讀多寫少,何不分離開來,增長架構的效率

增長中間層,任何的增刪改查都走中間層,來分配路由到後端

企業讀寫分離及分庫分表方案介紹

 

Mysql-proxy(oracle)  已再也不開發
Mysql-router(oracle) 重點關注
Atlas (Qihoo 360) 輕量級,簡單
Atlas-sharding (Qihoo 360)
Cobar(是阿里巴巴(B2B)部門開發) 已再也不更新
Mycat(基於阿里開源的Cobar產品而研發) 
TDDL Smart Client的方式(淘寶)
DRDS 阿里雲的產品 
Oceanus(58同城數據庫中間件)
OneProxy(原支付寶首席架構師樓方鑫開發)
vitess(谷歌開發的數據庫中間件)
Heisenberg(百度)
TSharding(蘑菇街白輝)
Xx-dbproxy(金山的Kingshard、噹噹網的sharding-jdbc )amoeba

 

 

 

Atlas簡介

 

Atlas 是由 Qihoo 360公司Web平臺部基礎架構團隊開發維護的一個基於MySQL協議的數據中間層項目。
它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基礎上,修改了大量bug,添加了不少功能特性。
目前該項目在360公司內部獲得了普遍應用,不少MySQL業務已經接入了Atlas平臺,天天承載的讀寫請求數達幾十億條。 源碼 Github: https:
//github.com/Qihoo360/Atlas

 

 

 

你理解的中間層應該能作些啥?

1、監控
2、對應用透明,有IP,port
3、分析語句
4、進行語句的路由
5、有負載均衡的功能
6、平滑上下線節點的能力
7、黑名單等

 

Atlas主要功能介紹

 

讀寫分離
從庫負載均衡
自動分表
IP過濾
SQL語句黑白名單
DBA可平滑上下線DB
自動摘除宕機的DB

 

 

 

Atlas應用場景介紹

 

Atlas是一個位於前端應用與後端MySQL數據庫之間的中間件,
它使得應用程序員無需再關心讀寫分離、分表等與MySQL相關的細節,能夠專一於編寫業務邏輯,
同時使得DBA的運維工做對前端應用透明,上下線DB前端應用無感知。

 

 

 

Atlas安裝配置

 

下載地址:https://github.com/Qihoo360/Atlas/releases

注意:
1、Atlas只能安裝運行在64位的系統上
2、Centos 5.X安裝 Atlas-XX.el5.x86_64.rpm,Centos 6.X安裝Atlas-XX.el6.x86_64.rpm。
3、後端mysql版本應大於5.1,建議使用Mysql 5.6以上
安裝在了10.0.0.53

 

 

 

安裝和配置

 

1、安裝軟件
rpm -ivh Atlas-2.2.1.el6.x86_64.rpm 

2、修改配置
cd /usr/local/mysql-proxy/

vim /usr/local/mysql-proxy/conf/test.cnf  # 本來的文件裏面有中文的註釋,解釋每一行的做用
[mysql-proxy]
admin-username = user
admin-password = pwd
proxy-backend-addresses = 10.0.0.55:3306   主庫 寫操做 vip
proxy-read-only-backend-addresses = 10.0.0.52:3306,10.0.0.53:3306  按照環境修改從庫地址
pwds = repl:3yb5jEku5h4=,mha:O2jBXONX098=   後端數據庫帳號和密碼,須要提早規劃好用戶和權限
daemon = true
keepalive = true
event-threads = 8
log-level = message
log-path = /usr/local/mysql-proxy/log
sql-log=ON
proxy-address = 0.0.0.0:33060   容許全部地址,經過端口33060 連接atlas
admin-address = 0.0.0.0:2345   管理atlas的地址
charset=utf8

/usr/local/mysql-proxy/bin/encrypt  123      ---->製做加密密碼的命令

3、啓動atlas /usr/local/mysql-proxy/bin/mysql-proxyd test start ps -ef |grep proxy ---------------------- netstat -lntup | grep proxy 看是否兩個端口號都生成了
ps -ef |grep proxy 看應用是否起來
4、測試 測試讀寫分離: 讀的測試 mysql -uroot -p123 -h10.0.0.53 -P33060 show variables like 'server_id';能夠看到在兩個從指間切換 寫操做測試: 設置兩個從節點只讀 set global read_only=1; 臨時設置爲只讀庫 鏈接測試 mysql -umha -pmha -h10.0.0.53 -P33060 create database db1;

Atlas配置文件說明

 

Atlas基本管理

鏈接管理接口:
mysql -uuser -ppwd -h127.0.0.1 -P2345
打印幫助:
mysql> select * from help;查看到全部管理命令
動態添加刪除節點: REMOVE BACKEND
3;
添加節點: ADD SLAVE
10.0.0.53:3306;
在線改配置,使重啓後依然生效
SAVE CONFIG;

atlas自動分表功能

數據條數達到800萬後,索引的層次會很深,影響性能

school.stu    1000w
id   name 
實現拆分
stu_0   stu_1   stu_2   stu_3    stu_4

以上分表方式,存數據很是均勻,取數據不均與,由於要考慮業務需求
若是業務查詢熱點數據集中在id是1-200w這些數據,那麼讀取就不均勻
取模分表
n/5  取餘數  (0,1,2,3,4) 
(1)若是是  0  則分到 stu_0
(2)若是是  1  則分到 stu_1
(3)若是是  2  則分到 stu_2
(4)若是是  3  則分到 stu_3
(5)若是是  4  則分到 stu_4

取餘數
-------------------------------------
配置文件 vim /usr/local/mysql-proxy/conf/test.cnf
加入 tables
= school.stu.id.5 (主庫)手工建立,分表後的庫和表,分別爲定義的school 和 stu_0 stu_1 stu_2 stu_3 stu_4
mysql -umha -pmha h10.0.0.53 -P33060 create database school; use school create table stu_0 (
id int,name varchar(20)); create table stu_1 (id int,name varchar(20)); create table stu_2 (id int,name varchar(20)); create table stu_3 (id int,name varchar(20)); create table stu_4 (id int,name varchar(20)); 重啓atlas
測試: insert into stu values (
3,'wang5'); insert into stu values (2,'li4'); insert into stu values (1,'zhang3'); insert into stu values (4,'m6'); insert into stu values (5,'zou7'); commit;

查詢的時候,必須加上where條件,不能作範圍查詢,只能作等值查詢

擴展功能介紹

讀寫分離
    Atlas會透明的將事務語句和寫語句發送至主庫執行,讀語句發送至從庫執行。具體如下語句會在主庫執行
    顯式事務中的語句
    autocommit=0時的全部語句
    含有select GET_LOCK()的語句
    除SELECT、SET、USE、SHOW、DESC、EXPLAIN外的

從庫負載均衡
  proxy-read-only-backend-addresses=ip1:port1@權重,ip2:port2@權重

自動分表(已詳細配置過)
    使用Atlas的分表功能時,首先須要在配置文件test.cnf設置tables參數。
  tables參數設置格式:數據庫名.表名.分表字段.子表數量,
  好比:
  你的數據庫名叫school,表名叫stu,分表字段叫id,總共分爲2張表,
  那麼就寫爲school.stu.id.2,若是還有其餘的分表,以逗號分隔便可。
  用戶須要手動創建2張子表(stu_0,stu_1,注意子表序號是從0開始的)。
  全部的子表必須在DB的同一個database裏。
  當經過Atlas執行(SELECT、DELETE、UPDATE、INSERT、REPLACE)操做時,
  Atlas會根據分表結果(
id%2=k),定位到相應的子表(stu_k)。例如,執行select * from stu where id=3;,
  Atlas會自動從stu_1這張子表返回查詢結果。但若是執行SQL語句(select * from stu;)時不帶上id,則會提示執行stu 表不存在。   Atlas暫不支持自動建表和跨庫分表的功能。   Atlas目前支持分表的語句有SELECT、DELETE、UPDATE、INSERT、REPLACE。 IP過濾:client-ips   該參數用來實現IP過濾功能。   在傳統的開發模式中,應用程序直接鏈接DB,所以DB會對部署應用的機器(好比web服務器)的IP做訪問受權。   在引入中間層後,由於鏈接DB的是Atlas,因此DB改成對部署Atlas的機器的IP做訪問受權,
  若是任意一臺客戶端均可以鏈接Atlas,就會帶來潛在的風險。   client
-ips參數用來控制鏈接Atlas的客戶端的IP,能夠是精確IP,也能夠是IP段,以逗號分隔寫在一行上便可。   如:   client-ips=192.168.1.2, 192.168.2
  這就表明192.168.1.2這個IP和192.168.2.*這個段的IP能夠鏈接Atlas,其餘IP均不能鏈接。   若是該參數不設置,則任意IP都可鏈接Atlas。   若是設置了client-ips參數,且Atlas前面掛有LVS,則必須設置lvs-ips參數,不然能夠不設置lvs-ips。 SQL語句黑白名單   Atlas會屏蔽不帶where條件的delete和update操做,以及sleep函數。

 

Atlas-Sharding版本介紹

    Sharding的基本思想就是把一個數據表中的數據切分紅多個部分, 存放到不一樣的主機上去(切分的策略有多種), 
從而緩解單臺機器的性能跟容量的問題. sharding是一種水平切分, 適用於單表數據龐大的情景.
目前atlas支持靜態的sharding方案, 暫時不支持數據的自動遷移以及數據組的動態加入. Atlas以表爲單位sharding, 同一個數據庫內能夠同時共有sharding的表和不sharding的表,
不sharding的表數據存在未sharding的數據庫組中. 目前Atlas sharding支持insert, delete,
select, update語句, 只支持不跨shard的事務.
全部的寫操做如insert, delete, update只能一次命中一個組,
不然會報"ERROR 1105 (HY000):write operation is only allow to one dbgroup!"錯誤. 因爲sharding取替了Atlas的分表功能, 因此在Sharding分支裏面, Atlas單機分表的功能已經移除, 配置tables將不會再有效.

 

Atlas-Sharding架構*

配置示例

    Atlas支持非sharding跟sharding的表共存在同一個Atlas中, 2.2.1以前的配置能夠直接運行. 以前的配置如
proxy-backend-addresses = 192.168.0.12:3306 
proxy-read-only-backend-addresses = 192.168.0.13:3306,192.168.0.14:3306 ... 
這配置了一個master和兩個slave, 這屬於非sharding的組, 全部非sharding的表跟語句都會發往這個組內.
因此以前沒有Sharding的Atlas的表能夠無縫的在新版上使用, 注意: 非Sharding的組只能配置一個, 而sharding的組能夠配置多個. 下面的配置, 配置了Sharding的組, 注意與上面的配置區分 [shardrule
-0] table = test.sharding_test #分表名,有數據庫+表名組成 type = range #sharding類型:range 或 hash shard-key = id #sharding 字段 groups = 0:0-999,1:1000-1999 #分片的group,若是是range類型的sharding,則groups的格式是:group_id:id範圍。
若是是hash類型的sharding,則groups的格式是:group_id。例如groups
= 0, 1 [group-0] proxy-backend-addresses=192.168.0.15:3306 proxy-read-only-backend-addresses=192.168.0.16:3306 [group-1] proxy-backend-addresses=192.168.0.17:3306 proxy-read-only-backend-addresses=192.168.0.18:3306

 

 Sharding測試案例*

建立測試表:
DROP TABLE IF EXISTS `sharding_test`; 
CREATE TABLE `sharding_test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` char(50) 
COLLATE utf8_bin NOT NULL, `age` int(11) DEFAULT NULL, `birthday` date DEFAULT NULL,
`nickname` char(50) COLLATE utf8_bin DEFAULT NULL, PRIMARY KEY (`id`) ) mysql -h127.0.0.1 –P33060 -uroot -pmysqltest –c mysql> use test; mysql> insert into sharding_test(id, name, age) values(1, 'test', 0); mysql> insert into sharding_test(id, name, age) values(50, 'test', 0), (999, 'test', 0); 注意: 以上幾條數據都插入到了dbgroup0, 請注意第二條多值插入的語句, 由於50和999都命中了dbgroup0, 因此其執行成功, 可是若是執行如下的語句: mysql> insert into sharding_test(id, name, age) values(100, 'test', 0), (1500, 'test', 0);
ERROR 1105 (HY000): Proxy Warning - write operation is only allow to one dbgroup! 在sharding的表中, 這是不容許的, 由於id爲100命中了dbgroup0, 而id爲1500 命中了dbgroup1,
因爲分佈式的多值插入可能致使部分紅功, 須要回滾, 這個Atlas暫不支持. update, delete, replace同理. 測試完成分別登錄兩個主庫進行查看數據。

 

 sharding限制

關於支持的語句
Atlas sharding只對sql語句提供有限的支持, 目前支持基本的Select, insert/replace, delete, update語句, 
支持所有的Where語法(SQL-92標準), 不支持DDL(create drop alter)以及一些管理語句,
DDL請直連MYSQL執行, 請只在Atlas上執行Select, insert, delete, update(CRUD)語句. 對於如下語句, 若是語句命中了多臺dbgroup, Atlas均未作支持(若是語句只命中了一個dbgroup,
如select count(
*) from test where id < 1000, 其中dbgroup0範圍是0 - 1000, 那麼這些特性都是支持的) Limit Offset(支持Limit) Order by Group by Join ON Count, Max, Min等函數 增長節點 注意: 暫時只支持range方式的節點擴展, hash方式因爲須要數據遷移, 暫時未作支持. 擴展節點在保證原來節點的範圍不改變的狀況下, 如已有dbgroup0爲範圍0 - 999, dbgroup1爲範圍 1000 - 1999,
這個時候能夠增長範圍>2000的節點. 如增長一個節點爲2000 - 2999, 修改配置文件, 重啓Atlas便可.

1五、MySQL優化

優化哲學

  • 優化不老是對一個單純的環境進行!還極可能是一個複雜的已投產的系統。
  • 優化手段原本就有很大的風險,只不過你沒能力意識到和預見到!
  • 任何的技術能夠解決一個問題,但必然存在帶來一個問題的風險!
  • 對於優化來講解決問題而帶來的問題控制在可接受的範圍內纔是有成果。
  • 保持現狀或出現更差的狀況都是失敗!
  • 穩定性和業務可持續性一般比性能更重要!
  • 優化不可避免涉及到變動,變動就有風險!不要隨意變動生產中的軟件參數!
  • 優化使性能變好,維持和變差是等機率事件!
  • 優化不能只是數據庫管理員擔當風險,但會全部的人分享優化成果!
  • 因此優化工做是由業務須要驅使的!!!

誰參與優化

- 數據庫管理員
- 業務部門表明
- 應用程序架構師
- 應用程序設計人員
- 應用程序開發人員
- 硬件及系統管理員
- 存儲管理員

優化方向

- 安全優化(業務持續性)
- 性能優化(業務高效性)

優化範圍

存儲、主機和操做系統:
    主機架構穩定性
    I/O規劃及配置
    Swap
    OS內核參數和網絡問題
應用程序:
    應用程序穩定性
    SQL語句性能
    串行訪問資源
    性能欠佳會話管理
數據庫優化:
    內存
    數據庫結構(物理&邏輯)
    實例配置

優化成本:由上往下依次增高
優化效果:由下往上依次增高
    由以上圖示能夠看出,咱們若是想要深度優化MySQL數據庫,須要作的事情不是單方面的,而是要從成本及優化
效果選擇最適合當前企業需求的方案。因此本課程針對整個出發點,會從各個維度來讓MySQL在運行過程當中達到最優的
狀態。

優化工具

操做系統
  top, 
  iostat 、
  vmstat、
  nmon、
  dstata 數據庫   基礎優化命令工具 mysql SHOW [SESSION
| GLOBAL] STATUS SHOW ENGINE INNODB STATUS SHOW PROCESSLIST show index Information Schema mysqldumpslow explain msyqladmin mysqlshow   深度優化命令工具(擴展) mysqlslap sysbench  mysql profiling Performance Schema

優化思路

思路:
    定位問題:
        硬件
        系統    
        應用
        數據庫    
        架構(高可用、讀寫分離、分庫分表)
    處理問題
        明確優化目標
        性能和安全的折中
        防患未然

工具詳細介紹

1、系統優化工具 1.1 top 
  [root@Dao ~]# top
  top - 23:52:39 up 14:39,  1 user,  load average: 0.00, 0.01, 0.05
  Tasks:  67 total,   1 running,  66 sleeping,   0 stopped,   0 zombie
  %Cpu(s):  0.3 us,  0.0 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0
  KiB Mem :  1014892 total,   668044 free,    62020 used,   284828 buff/cache
  KiB Swap:        0 total,        0 free,        0 used.   800696 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND   
   3284 root      10 -10  125300  11640   9116 S  0.3  1.1   2:40.03 AliYunDun (
1)簡介: 實時監控當前操做系統的負載狀況的,每秒刷新一次狀態,一般會關注三大指標(CPU、MEM、IO) (2)評判標準 (2.1) 總體的負載狀況,判斷標準,若是值很是高,只能告訴咱們操做系統很繁忙 load average: 0.00, 0.00, 0.002.2)CPU使用狀況 Cpu(s): 0.2%us, 0.2%sy, 99.7%id, 0.0%wa %id: CPU空閒的百分比 問一個問題?你以爲在一個已投產的系統中ID值是高好仍是低好呢? 通常狀況下咱們建議,95%如下都算是正常的,可是呢,咱們去準備硬件的時候,通常都會預留一部分(3年)
硬件配置
%us:用戶程序,佔用的CPU時間片的百分比。咱們認爲us%高是好事,但要在cpu正常能力範圍內。 %sy:系統程序(和內核工做有關),資源調配,資源管理,內核其餘功能的管理(system call) 對於比較成熟的操做系統,對sy%應該是佔比不多的。咱們認爲越少越好。 若是飆升,可能說明兩件事情,1,系統bug;2,中病毒了 %wa 這個參數越少越好。若是wait高說明了, 1,IO很慢(速度慢,全表掃描) 2、內存滿了OOM(內存小,全表掃描) (2.3) Mem: 4040596k total, 1692536k used, 2348060k free, 152348k buffers Swap: 786428k total, 0k used, 786428k free, 620256k cached Mem: total:總的內存量 used:已經被使用的內存量 free:空閒的內存空間 buffer:專門負責操做系統當中,與文件修改類操做有關的內存緩衝區(專門負責寫操做的),
    能夠被重複利用的內存區域 cached:專門負責操做系統當中,與文件讀取有關的緩存區域(專門負責文件讀取操做的),     對於操做系統可用內存量
=free+buffer+cached used:used=RSS+anon+buffer+cached 補充: 1.Linux操做系統內存劃分的三大區域: RSS:常駐內存集,主要負責程序運行須要的內存區域 Page Cache:頁緩存,文件系統緩存(FS cache),主要負責文件有關的緩衝和緩存,buffer+cached anon page: 匿名頁,主要負責程序之間交互時使用到內存區域 2.連續的地址位,定義爲了page(頁),而且進行了量化。 (1)基於固定大小page分配模式,他的一些不足的地方? 在申請內存時,須要整個內存進行遍歷 會有大量的內存碎片,致使程序OOM(out of memory) (2)SLAB Allocator內存管理子系統 1、將內存邏輯化成chain+chunk模式,內存區域會有多條鏈。
    每條chain下都「掛着」多個等同大小的chunk(2的冪)
2、在每條鏈的頭部,都會有一個專門的chunk位圖,來更快速的找到須要的空閒chunk,
    而且記錄每一個chunk最後被訪問的時間戳。 (
3)buddy system(夥伴系統) 1、提供了多種內存實現回收和整理內存碎片算法,最經典的就是LRU算法。 2、當內存free空間緊張時,會觸發進行整理或釋放,再也不使用buffer和cached 經過如下命令,手工釋放全部buffer和cached echo 3 > /proc/sys/vm/drop_caches SWAP:交換分區,當內存緊張的時候,會將內存區域當中的數據臨時置換到SWAP中。 默認:在內存使用量達到60% [root@db02 ~]# cat /proc/sys/vm/swappiness 控制參數 60
主要交換有哪些
buffer 中爲修改完成的,RSS,anon_page
對於MySQL環境,要儘可能避免swap使用 sysctl.conf swappiness=0 臨時修改: [root@db02 ~]# echo 0 >/proc/sys/vm/swappiness 2、iostat 測試當前環境IO水平
[root@Dao ~]# iostat 1 10 # 每1秒顯示一次,共顯示10次
[root@Dao ~]# iostat -dk 1 5 # 以KB爲單位,每1秒顯示一次,顯示5次
mount /dev/sdb /data iostat -dm 1 /dev/sdb # 以MB爲單位,每1s顯示一次sdb的狀況 ,不停 dd if=/dev/zero of=/data/bigfile 一直寫文件 在優化過程當中,咱們通常會結合CPU和內存的使用狀況看IO狀態 CPU很是繁忙(MYSQL): 1、user 很高 再看IO水平,正常狀況下IO也會很高 不正常的狀況,user很高,可是IO很低? 在作大量的計算(多表鏈接查詢、排序、分組、子查詢很複雜或者很頻繁) 2wait 很高 IO不多 (1)頗有多是全表掃描 (2)IO有問題(RAID規劃或者磁盤IO自己問題) 3、vmstat 用法和iostat相似,是一個綜合判斷的命令
vmstat
1 10 [root@Dao ~]# vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 531816  45680 375384    0    0     1     2   90  105  0  0 100  0  0
 0  0      0 531792  45680 375384    0    0     0     0  102  258  0  0 100  0  0
 0  0      0 531792  45680 375384    0    0     0     0   97  250  0  0 100  0  0
 0  0      0 531792  45680 375384    0    0     0     0  100  255  0  0 100  0  0
 0  0      0 531792  45680 375384    0    0     0     0  101  253  0  1 99  0  4、dstat
須要單獨安裝 yum install dstat -y 也是一個綜合命令,直接使用,比較人性化,自動設置顯示的單位,仍是彩色的,換頁自動顯示錶頭,很cool

顯示了cpu、磁盤、網絡IO、swap(paging space)、系統相關
2、數據庫層面優化工具 基礎優化命令工具 (1)mysql 用法舉例: mysql -uroot -p123 -e "show status like '%lock%'"2)SHOW ENGINE INNODB STATUS mysql> show engine innodb status\G 通常關注比較多的: 內存、線程、鎖相關 (3)show index from table 查看索引狀況 (4)Information Schema 能夠直接使用show命令查看裏面的內容 (5)mysql庫下的 innodb_table_stats innodb_index_stats
  desc innodb_table_stats 看錶的使用狀況
  select * from innodb_table_stats
  select * from innodb_index_stats; 索引的使用狀況和跟新狀態 (
6) 用的最多的SHOW [SESSION | GLOBAL] STATUS (7) SHOW [FULL] PROCESSLIST(應急調優) (8) explain 查看執行計劃 (9) mysqldumpslow (pt-query-diagest) 分析慢日誌 深度優化命令工具(擴展) mysqlslap sysbench tpcc
以上三個都是壓力測試工具 Performance Schema(
5.7默認開啓)-能夠重點關注,用於定位數據庫問題 -----------------------------------------

企業基礎優化實戰(壓力測試例子)

硬件優化

硬件優化:
主機:
    根據數據庫類型,主機CPU選擇、內存容量選擇、磁盤選擇
    平衡內存和磁盤資源
    隨機的I/O和順序的I/O
    主機 RAID卡的BBU(Battery Backup Unit)關閉
存儲:
    根據存儲數據種類的不一樣,選擇不一樣的存儲設備
    配置合理的RAID級別(raid五、raid十、熱備盤)
網絡設備:
    使用流量支持更高的網絡設備(交換機、路由器、網線、網卡、HBA卡)
注意:這些規劃應該在初始設計系統時就應該 考慮
--------------------------------------------------------
詳細說明 主機: 根據數據庫類型 (1)主機CPU選擇 IO密集型:能夠處理多併發的CPU類型,特色是核心數量較多,主頻中等 Intel E系列 CPU密集型:能夠處理高性能計算的cpu類型,主頻很是高,核心數量中等 Intel I系列的 MySQL的線上業務,處理高併發訪問的業務。屬於IO密集型的業務,因此選擇志強系列的CPU更好一些。 MySQL非線上的業務,數據處理數據分析,算法計算,屬於CPU密集型業務,因此選擇I系列的CPU。 (2)內存容量選擇 通常是選擇cpu核心數量的2倍 (3)IO的選擇 1、磁盤選擇 SATAIII SAS FC SSD pci-e SSD Flash 主機 RAID卡的BBU(Battery Backup Unit)關閉 存儲(有條件的公司會選擇單獨存儲設備): 根據存儲數據種類的不一樣,選擇不一樣的存儲設備 配置合理的RAID級別(raid五、raid十、熱備盤) raid0 :性能高(條帶化),安全性和單盤同樣 raid1 :安全性高(條帶化功能),性能和單盤同樣 raid10 :讀寫性能都很高(0級別條帶化功能),安全性高(1級別,鏡像功能),企業若是有條件推薦的一種raid級別 raid5 :較好的安全性(校驗),較好的性能(條帶化功能,讀性能比較高,寫性能通常),
        對於讀多寫少的業務能夠使用此級別 高端存儲:IBM EMC HDS,通常都是raid1(就是raid10) ,自帶條帶化功能,並且只支持4塊盤作一個raid 使用合適raid級別,避免過分條帶化 ,條帶化增長了IO次數(相同量的數據) IOPS峯值:對於每一塊硬件磁盤來說,都有一個固定參數IOPS,每秒最多可以進行的IO的次數。 網絡設備: 使用流量支持更高的網絡設備(交換機、路由器、網線、網卡、HBA卡) 網卡綁定:解決網絡傳輸的可靠性, bonding 0(負載均衡模式) 1(主備模式) 添加備用網卡,交換機,預防線路故障 交換機:堆疊 0模式的綁定,要進行交換機的之間的綁定(連接成相似一臺的狀態),若是不作,會發生丟包
 

系統優化

系統優化
Cpu:
    基本不須要調整,在硬件選擇方面下功夫便可。
內存:
    基本不須要調整,在硬件選擇方面下功夫便可。
SWAP:
    MySQL儘可能避免使用swap。
IO :
    raid
    no lvm
    ext4或xfs
    ssd
    IO調度策略
--------------------------------------------------------
詳細說明
系統層面優化: 1、Swap調整 /proc/sys/vm/swappiness的內容改爲0(臨時) echo 0>/proc/sys/vm/swappiness /etc/sysctl.conf上添加vm.swappiness=0(永久) vim /etc/sysctl.conf vm.swappiness=0 sysctl -p 這個參數決定了Linux是傾向於使用swap,仍是傾向於釋放文件系統cache。
在內存緊張的狀況下,數值越低越傾向於釋放文件系統cache。 固然,這個參數只能減小使用swap的機率,並不能避免Linux使用swap。
注: 修改MySQL的的配置參數innodb_flush_method,並開啓O_DIRECT模式。
這種狀況下,IonnDB的buffer pool會直接繞過cache來訪問磁盤,
可是redo log依舊會使用文件系統的cache。
值得注意的是,Redo log是覆寫模式,即便使用了文件系統的cache,也不會佔用太多

2、IO調度策略 臨時修改: [root@db02 ~]# cat /sys/block/sda/queue/scheduler noop anticipatory deadline [cfq] 修改前是cfq(先進先出) [root@db02 ~]# cat /sys/block/sdb/queue/scheduler noop anticipatory deadline [cfq] [root@db02 ~]# echo deadline >/sys/block/sda/queue/scheduler [root@db02 ~]# echo deadline >/sys/block/sdb/queue/scheduler [root@db02 ~]# cat /sys/block/sdb/queue/scheduler noop anticipatory [deadline] cfq 修改後(mysql比較適合dedline) [root@db02 ~]# 永久修改:
vim /boot/grub.conf 在文件的下面內容中加入參數elevator=deadline,重啓後生效
kernel /vmlinuz-2.6.32-696.el6.x86_64 ro root=UUID=40c9133f-6007-485c-be19-4082c8361df3 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 
rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM elevator=deadline rhgb quiet 3、FS: NO LVM 儘可能不要使用LVM ext4或xfs 文件系統的選擇 ssd(binlog relay可能單獨存放在ssd上) 4、關閉無用服務 chkconfig --level 23456 acpid off chkconfig --level 23456 anacron off chkconfig --level 23456 autofs off chkconfig --level 23456 avahi-daemon off chkconfig --level 23456 bluetooth off chkconfig --level 23456 cups off chkconfig --level 23456 firstboot off chkconfig --level 23456 haldaemon off chkconfig --level 23456 hplip off chkconfig --level 23456 ip6tables off chkconfig --level 23456 iptables off chkconfig --level 23456 isdn off chkconfig --level 23456 pcscd off chkconfig --level 23456 sendmail off chkconfig --level 23456 yum-updatesd off

Linux系統內核參數優化

vm.swappiness=0
用戶限制參數
    /etc/security/limits.conf    
  * soft nproc 65535 
  * hard nproc 65535 
  * soft nofile 65535 
  * hard nofile 65535

應用優化

業務應用和數據庫應用獨立
防火牆:iptables   selinux
其餘(關閉無用服務):
    chkconfig --level 23456 acpid off
    chkconfig --level 23456 anacron off
    chkconfig --level 23456 autofs off
    chkconfig --level 23456 avahi-daemon off
    chkconfig --level 23456 bluetooth off
    chkconfig --level 23456 cups off
    chkconfig --level 23456 firstboot off
    chkconfig --level 23456 haldaemon off
    chkconfig --level 23456 hplip off
    chkconfig --level 23456 ip6tables off
    chkconfig --level 23456 iptables  off
    chkconfig --level 23456 isdn off
    chkconfig --level 23456 pcscd off
    chkconfig --level 23456 sendmail  off
    chkconfig --level 23456 yum-updatesd  off

另外,思考未來咱們的業務是否真的須要MySQL,仍是使用其餘種類的數據庫。  以上:硬件優化建議,操做系統優化建議,應該在業務架構搭建初始應該作好。 

數據庫優化

 
 
數據庫層面優化:
4.1 參數優化(見參數優化建議.txt4.2 數據庫索引優化(見索引管理章節) 4.3 鎖優化 4.4 數據庫架構優化(擴展)

參數調整: 實例總體(高級優化,擴展): thread_concurrency 併發線程數量個數 sort_buffer_size 排序緩存 read_buffer_size 順序讀取緩存 read_rnd_buffer_size 隨機讀取緩存 key_buffer_size 索引緩存 thread_cache_size (1G —
> 8, 2G —> 16, 3G —> 32, >3G —> 64) 鏈接層(基礎優化) 設置合理的鏈接客戶和鏈接方式 max_connections 最大鏈接數 max_connect_errors 最大錯誤鏈接數 connect_timeout 鏈接超時 max_user_connections 最大用戶鏈接數 skip-name-resolve 跳過域名解析 wait_timeout 等待超時 back_log 能夠在堆棧中的鏈接數量 SQL層(基礎優化) query_cache_size 查詢緩存 存儲引擎層(innodb基礎優化參數) default-storage-engine innodb_buffer_pool_size innodb_file_per_table=(1,0) innodb_flush_log_at_trx_commit=(0,1,2) Innodb_flush_method=(O_DIRECT, fdatasync) innodb_log_buffer_size innodb_log_file_size innodb_log_files_in_group innodb_max_dirty_pages_pct log_bin max_binlog_cache_size max_binlog_size innodb_additional_mem_pool_size(於2G內存的機器,推薦值是20M。32G內存的 100M) transaction_isolation
  SQL優化:
        執行計劃(基礎優化)
        索引(基礎優化)
        SQL改寫(高級優化)
    架構優化(高級優化擴展):
      高可用架構
      高性能架構
      分庫分表
-----------------------------------------------

 鎖優化-減小死鎖和處理死鎖

鎖優化
MyIASM: 表級鎖
優勢:申請和釋放時,須要更少系統資源,減小死鎖產生。
缺點:不利於併發處理,在某個事務在對錶進行修改操做時,會鎖定整個表,其餘事務只能等待完成以後,才能操做。
有很是嚴重的鎖等待。

InnoDB:
    支持行級鎖,行級鎖在索引鎖。若是表中沒有任何索引,那麼咱們作表數據處理的時候,依然會表級鎖。
    GAP鎖:主要針對範圍數據操做時

死鎖的處理過程:
1、show processlist
2、show  engine innodb status\G;
LOCK WAIT 2 lock struct(s), heap size 1184, 1 row lock(s)
MySQL thread id 4, OS thread handle 0x7f37d66f0700, query id 44 localhost root Sending data
select * from t1 where id=3 for update
Trx read view will not see trx with id >= 2323, sees < 2323
------- TRX HAS BEEN WAITING 3 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 14 page no 3 n bits 72 index `GEN_CLUST_INDEX` of table `test`.`t1` trx id 2322 lock_mode X waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 0

3kill 4;

避免死鎖的方法:
(1)將index lock 轉換爲table lock
set autocommit=0;
lock table t1;
insert to
update
delete
commit
unlock table t1;
(2)將全部事務處理表數據的順序儘可能保證一致。

做業

一、搭建MHA+Atlas高可用讀寫分離架構

要求: 畫出實驗拓撲圖,標準清楚IP/hostname/做用 (1)實現1主2從GTID主從複製環境 (2)構建MHA高可用環境 (3)模擬損壞主庫,並實現修復 (4)實現應用透明(VIP) (5)實現外部數據補償(binlog server) (6)基於MHA環境實現Atlas讀寫分離 (7)在線增長刪除節點管理Atlas 
相關文章
相關標籤/搜索