日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql锁简谈_mysql锁简谈

發布時間:2025/4/5 数据库 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql锁简谈_mysql锁简谈 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.mysql鎖,

作用:解決因資源共享而造成的并發問題。

實例:買最好一件衣服X

A: X 買: X加鎖----->試衣服……下單……付款……打包….------>X解鎖

B: X 買: 發現X已被加鎖,等待X解鎖,X已售空

分類 :

操作類型:

A.讀鎖(共享鎖):對同一個數據(衣服),多個讀操作可以同時進行,互不干擾

B.寫鎖(互斥鎖):如果當前寫操作沒有完畢(買衣服的一系列操作),則無法進行其他的讀操作,寫操作。

操作范圍:

A.表鎖:一次性對一張表整體加鎖.

如:MYISAM存儲引擎使用表鎖,開銷小,加鎖快,無死鎖;

但鎖的范圍大,容易發生鎖沖突,并發度低;

B.行鎖:一次性對一條數據加鎖

如:INNODB存儲引擎使用行鎖,開銷大,加鎖慢,容易出現死鎖;

但鎖的范圍較小,不易發生鎖沖突,并發度高(很小概率發生高并發問題:臟讀,幻讀,不可重復讀,丟失更新等)

實例:

表鎖: 自增操作mysql/sqlserver支持,Oracle需要借助于序列來實現自增

Create table tablelock

(

Id int primary key auto_increment,

Name varchar(20)

)engine myisam;

Insert into tablelock(name) values('a1')

Insert into tablelock(name) values('a2')

Insert into tablelock(name) values('a3')

Insert into tablelock(name) values('a4')

Insert into tablelock(name) values('a5')

查看加鎖的表: show open tables; desc emp;查表結構

增加鎖: locak table 表1 read/write , 表2 read/write , …..

回話1:session

加讀鎖:locak table tablelock read;

select * from tablelock; -----讀,可以

delete from tablelock where id=1;-------寫(增刪改),不可以

Select * from emp;-----讀,不可以

Delete from emp where eno=1;------寫,不可以

總結:會話1如果給A表加了讀鎖,則當前會話只能對A表進行讀操作,其他表都不能操作

會話2(其它會話):

Select * from tablelock;-------讀,可以

Delete from tablelock where id=1;-----寫,會“等待”會話1解鎖為止

Select * from emp;-------讀,可以

Delete from emp where eno=1;--------寫,可以

總結:會話1給A表加了鎖,其它會話的操作:

A.可以除了A表的其它表進行讀,寫操作

B.對A表:讀,可以,寫要等待釋放鎖

釋放鎖:會話1執行, unlock tables;

2.加寫鎖:

會話1:

lock table tablelock write;

當前會話1,可以對加了鎖的表進行任何操作(增刪改查),但是不能操作(增刪改查)其它表

其它會話2,對會話1中加寫鎖的表,可以進行增刪改查的前提是:等待會話1釋放寫鎖

MySQL表極鎖的鎖模式

MyISAM在執行查詢語句(SELECT)前,會自動給涉及的所有表加讀鎖,在執行更新操作 (DML)前,會自動給涉及的表加寫鎖。

所以對MyISAM表進行操作,會有以下情況:

A.對MyISAM表的讀操作(加讀鎖),不會阻塞其它進程(會話)對同一表的讀請求,但會阻塞對同一表的寫請求。只有當讀鎖釋放后,才會執行其它進程的寫操作。

B.對MyISAM表的寫操作(加寫鎖),會阻塞其它進程(會話)對同一表的讀和寫操作,只有當寫鎖釋放后,才會執行其它進程的讀寫操作。

分析表鎖定:

查看哪些表加了鎖:show open tables;----1代表被加了鎖

分析表鎖定的嚴重程度:show status like ‘%table%’;

Table_locks_immediate:即可能獲取到的鎖數

Table_locks_waited:需要等待的表鎖數(如果該值越大,說明存在越大的鎖競爭)

一般建議Table_locks_immediate/Table_locks_waited>5000,則建議采用InnoDB引擎,否則用MyISAM引擎

行表(InnoDB)

Create table linelock(

Id int(5) primary key auto_increment,

Name varchar(20)

)engine=innodb;

Insert into linelock (name) values('1');

Insert into linelock (name) values('2');

Insert into linelock (name) values('3');

Insert into linelock (name) values('4');

Insert into linelock (name) values('5');

------mysql默認自動commit;Oracle默認不會自動commit;

為了研究行鎖,暫時關閉commit;set autocommit=0;以后每條都要commit

會話1:寫操作

Insert into linelock values(6,'a6'); -----------關閉commit后,在緩存里,commit后才生效

會話2:寫操作同樣的數據

Update linelock set name='ax' where id=6;---------想更新id為6的數據,執行時出現被鎖狀態,直到其它會話釋放(commit)后才能操作(行鎖)

提交:commit;丟棄:rollback;

對行鎖情況:

1.如果會話x對數據a進行DML操作(研究時關閉了自動commit的情況下),則其它會話必須等到會話x結束事務(commit/rollback)后,才能對數據a進行操作。

2.表鎖 是通過unlock tables; ,也可以通過事務解鎖。行鎖 是通過事務解鎖。

行鎖,一次鎖一行數據,因此,如果操作的是不同數據,則不干擾。

3.行鎖的注意事項:

A.如果沒索引,則行鎖會轉為表鎖

Show index from linelock;

Alter table linelock add index idx_linelock_name(name);

會話1:寫操作

Update linelock set name='ai' where name='3';

會話2:寫操作,不同的數據

Update linelock set name='aix' where name='4';

會話1:寫操作

update linelock set name='ai' where name=3;

會話2:寫操作,不同數據

update linelock set name='aix' where name=4;

-------->可以發現,數據被阻塞了(加鎖)

-------->原因:如果索引類 發生了類型轉換,則索引失效。因此此次操作,會從行鎖轉為表鎖。

B.行鎖的一種特殊情況:間隙鎖:值在范圍里,但卻不存在。

此時linelock表中,沒有id=7的數據

Update linelock set name='x' where id>1 and id<9;

mysql會自動給間隙加鎖---->間隙鎖,給id=7的數據加間隙鎖(行鎖)。

行鎖:如果有where,則實際加鎖的范圍就是where后面的范圍(不是實際的值)

行鎖:innodb默認采用行鎖

缺點:比表鎖性能消耗大

優點:并發能力強,效率高

建議:高并發用innodb,否則用myisam

分析:show status like '%innodb_row_lock%';

Innodb_row_lock_current_waits: 當前正在等待鎖的數量

Innodb_row_lock_time: 等待總時長,從系統啟動到現在一共等待的時間

Innodb_row_lock_time_avg:平均等待時間

Innodb_row_lock_time_max:最長等待時間

Innodb_row_lock_waits: 系統啟動到現在一共等待的次數

查詢行鎖:

關閉commit自動提交:

set autocommit;

start transaction;

begin;

for update對query語句加鎖

Select * from linelock where id=2 for update

4.主從復制:

優點:負載均衡

失敗遷移

Windows:mysql 主

Linux:mysql 從

(版本最好相近或相同)

圖形客戶端工具

SQLyog, Navicat

如果要遠程連接數據庫,則需要授權遠程訪問。

Windows:安裝時選擇可以遠程訪問

Linux:GRANT ALL PRIVILEGES ON *.* TO 'root' @'%' IDENTIFIED BY 'root' WITH GRANT OPTION;

FLUSH PRIVILEGES;

關閉防火墻:service iptables stop

主機Windows192.168.2.2:授權那個數據庫作為自己的slave

GRANT REPLICATION slave ,reload, super ON *.* TO 'root'@'192.168.2.%' IDENTIFIED BY 'root';

fulsh privileges;

show master status;

從機linux:授權那個數據庫作為自己的master

CHANGE MASTER TO MASTER_HOST ='192.168.2.2',MASTER_USER='root', MASTER_PASSWORD='root' ,MASTER_PORT=3306,

master_log_file='mysql-bin.000002', master_log_pos=667;

5.主從復制:

同步的核心:二進制文件binary log

對數據庫的增刪改查的操作都會備份到二進制文件里

從數據庫的I/O線程會從主數據庫讀二進制文件

Relay log通過sql線程寫到從數據庫

1.master將改變的數記錄在本地的二進制日志中(binary log):

該過程稱之為二進制日志事件

2.slave將master的binary log拷貝到自己的relay log(中繼日志文件)中

3.中繼日志事件,將數據讀取到自己的數據庫之中

mysql主從復制是異步,串行化的,有延遲的

master:slave=1:n

配置:

Windows:主mysql,my.ini

Linux:從mysql,my.cnf

配置前,為了無誤,先將各防火墻,權限(遠程訪問)處理好

主mysql,my.ini配置文件中:

[mysqld]下,server-id=1

log-bin="mysql安裝目錄/data/mysql-bin" ----二進制文件,注意是/,不是\

log-error="mysql安裝目錄/data/mysql-error" ---錯誤記錄文件

binlog-ignore-db=mysql ------主從同步時,忽略的數據庫

binlog-do-db=test ------主從同步時,同步哪些數據

Windows主mysql授權那臺從計算機

GRANT REPLICATION slave ,reload, super ON *.* TO 'root'@'192.168.2.%' IDENTIFIED BY 'root';

fulsh privileges;

show master status; ----查看主數據庫的狀態

File ,Position , Binlog_Do_DB , Binlog_Ignore_DB

Mysql-bin.000001 , 575 , test , mysql

重啟后二進制文件才有mysql-bin,mysql-error

File , Position(107)要變,每次在左主從同步前,需要觀察主機狀態的最新值

從mysql, my.cnf配置文件中:

[mysqld]下,server-id=2

log-bin=mysql-bin

replicate-do-db=test

linux中的從mysql授權那臺主計算機

從機linux:授權那個數據庫作為自己的master

CHANGE MASTER TO MASTER_HOST ='192.168.2.2',MASTER_USER='root', MASTER_PASSWORD='root' ,MASTER_PORT=3306,

master_log_file='mysql-bin.000001', master_log_pos=107;

如果報錯:This operation cannot be performed with a running slave ; run STOP SLAVE first

第一次不報錯,第二第三次出這個錯,

先STOP SLAVE; 再執行上面從mysql授權語句

開啟主從同步:

從機Linux:start slave ;

檢驗狀態: show slave status \G

主要觀察2個,slave_sql_running,slave_io_running , 要都是yes

如果不是yes,則看下方的日志 last_io_error,主從使用了相同的server-id,

檢查:在主從中分別查看server-id:show variables like '%server_id%' ; 發現確實都是1,但配置時是1,2,版本bug

Windows:5.5.56 ;Linux:5.5.58,可能5.5.58版本兼容性問題,或者是版本不同問題

解決:文件改不行,現在用全局變量改:set global server_id=2 ; (linux) , 設置了后關閉再開啟

演示:主mysql在test數據庫中新增表,插入數據,從mysql自動同步數據了.自此主從同步成功。

總結

以上是生活随笔為你收集整理的mysql锁简谈_mysql锁简谈的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。