<center id="qkqgy"><optgroup id="qkqgy"></optgroup></center>
  • <menu id="qkqgy"></menu>
    <nav id="qkqgy"></nav>
    <xmp id="qkqgy"><nav id="qkqgy"></nav>
  • <xmp id="qkqgy"><menu id="qkqgy"></menu>
    <menu id="qkqgy"><menu id="qkqgy"></menu></menu>
    <tt id="qkqgy"><tt id="qkqgy"></tt></tt>

  • 結論
    Sqlserver和Postgresql一樣,select堵塞ddl,ddl也堵塞select
    Oracle的話,select不堵塞DDL(0級鎖不堵塞6級鎖),DDL會堵塞select但不是表或行級別的鎖(堵塞類型是內存層面的library
    cache lock,所以傳統的說法6級鎖不堵塞0級鎖即寫不堵塞讀是沒問題的)
    Mysql的話,select堵塞DDL,DDL不直接堵塞select

    Oracle 19C的實驗
    CREATE TABLE t1 (h1 int,h2 char(200),h3 char(200),h4 char(200),h5 char(200))
    declare hid number:=1; begin loop insert into t1 (h1,h2,h3,h4,h5) values(hid,
    'hhhhhh2','hhhhhh3','hhhhhh4','hhhhhh5'); commit; hid:=hid+1; exit when hid>
    300000; end loop; commit; end;
    案例1
    會話1
    select count(*) from t1,t1
    備注:會話1執行完畢需要耗時10分鐘以上

    會話2
    drop table t1
    會話1執行過程中,會話2正常執行不會被堵塞,當會話2執行完后不久會話1報錯了ORA-08103: object no longer exists

    案例2
    會話1
    alter table t1 add t1_col varchar2(100) default '1222' not null
    備注1:會話1執行之前,需要執行alter system set “_add_col_optim_enabled”=false
    scope=spfile;,因為11G開始新增字段為非空并有默認值時并不會修改所有行,而是直接修改的數據字典,這樣的話執行alter table
    tablename add columnname default ‘value’ not
    null時會很快,為了模擬類似10G的新增字段為非空并有默認值時會修改所有行的操作,這就需要修改這個隱藏參數值,這樣就能使alter table
    tablename add columnname default ‘value’ not null這個ddl操作很慢
    備注2:t1是一張大表,會話1執行需要耗時10分鐘以上

    會話2
    select * from t1
    會話2被堵塞,會話1完成后會話2才能結束,但是堵塞事件是library cache lock而非表\行的lock

    Oracle結論:
    select不堵塞DDL(0級鎖不堵塞6級鎖),DDL會堵塞select(6級鎖堵塞0級鎖,但是和傳統理解中的寫不堵塞讀不是一個概念)
    查詢堵塞的語句:select sid,status,LOGON_TIME,sql_id,blocking_session
    "死鎖直接源",FINAL_BLOCKING_SESSION "死鎖最終源",event,seconds_in_wait
    "會話鎖住時間_S",LAST_CALL_ET "會話STATUS持續時間_S" from v$session where state='WAITING'
    and BLOCKING_SESSION_STATUS='VALID' and FINAL_BLOCKING_SESSION_STATUS='VALID'

    Sqlserver 2019的實驗
    CREATE TABLE t1 (h1 int,h2 char(200),h3 char(200),h4 char(200),h5 char(200))
    begin transaction insert1 declare @i int set @i=1 while @i<1000000 begin insert
    into t1 (h1,h2,h3,h4,h5) values(@i,'hhhhhh2','hhhhhh3','hhhhhh4','hhhhhh5'); set
    @i=@i+1 end commit transaction insert1
    案例1
    會話1
    select * from t1 order by table_name
    備注:t1是一張大表,會話1執行需要耗時10分鐘以上

    會話2
    drop table t1
    會話2被堵塞,堵塞事件是LCK_M_SCH_M

    案例2
    會話1
    alter table t1 add t1_col bigint IDENTITY (1,1) NOT NULL
    備注:t1是一張大表,會話1執行需要耗時10分鐘以上

    會話2
    select * from t1 或 select * from t1 with (nolock)
    會話2不管加不加with (nolock)都被堵塞,堵塞事件是LCK_M_SCH_M

    Sqlserver結論:
    select堵塞DDL,DDL堵塞select
    查詢堵塞的語句:select * from sys.sysprocess where blocked<>0

    Mysql 8.0的實驗
    CREATE TABLE testtable1 (h1 int(11),h2 char(200),h3 char(200),h4 char(200),h5
    char(200)) DELIMITER $$ CREATE PROCEDURE autoInsert3() BEGIN DECLARE i int
    default 1; START TRANSACTION; select sysdate(); WHILE(i < 100000) DO insert into
    testtable1(h1,h2,h3,h4,h5) value (i,'hhhhhhhhhhh2','hhhhhhhhhhh3',
    'hhhhhhhhhhh4','hhhhhhhhhhh5'); SET i = i+1; END WHILE; COMMIT; select sysdate()
    ; END$$ DELIMITER ;
    案例1
    會話1
    select count(*) from testtable1 a,testtable1 b,testtable1 c;
    會話1執行需要5分鐘

    會話2
    drop table testtable1;
    會話2被堵塞,會話1完成后會話2才能結束,堵塞事件是Waiting for table metadata lock

    案例2
    會話1
    alter table testtable1 add col_id1 int not null auto_increment,add key(col_id1)
    ;
    會話1執行需要5分鐘

    會話2
    select count(*) from testtable1 a,testtable1 b
    會話2不堵塞

    案例3
    會話1
    select count(*) from testtable1 a,testtable1 b,testtable1 c;
    會話1執行需要5分鐘

    會話2
    ALTER TABLE testtable1 ADD col_id4 int NOT NULL DEFAULT '110' 或 ALTER TABLE
    testtable1ADD col_id4 int NOT NULL DEFAULT '110',ALGORITHM=Inplace, LOCK=NONE;
    會話2被會話1堵塞,不管會話2加不加"ALGORITHM=Inplace, LOCK=NONE;"都會被堵塞,堵塞事件是Waiting for table
    metadata lock

    會話3
    select * from testtable1 limit 1;
    會話3顯示被會話1堵塞,會話3也顯示被會話2堵塞,堵塞事件是Waiting for table metadata lock

    案例4
    會話1
    alter table testtable1 drop col_id1;
    會話1執行需要5分鐘

    會話2
    select count(col_id1) from testtable1; 或 select col_id1 from testtable1;
    會話2不堵塞

    Mysql結論:

    select堵塞DDL,DDL不直接堵塞select,因為DDL其實類似重建表,Mysql重建表原理:先創建一張臨時表,MySQL會自動把原表數據拷貝到臨時表、再交換表名、再刪除舊表的操作。所以這個過程會堵塞DML但是不堵塞select,如果DDL也不想堵塞DML,則就是需要使用online
    DDL,online
    DDL原理:先創建一張臨時表,MySQL會自動把原表數據拷貝到臨時表、再拷貝原表數據到臨時表的過程中將所有對原表的DML操作記錄在一個日志文件,再把日志文件中的數據寫入到臨時表,再交換表名、再刪除舊表。
    查詢堵塞的語句:show full processlist;結合select * from sys.schema_table_lock_waits\G;

    Postgresql 11的實驗
    CREATE TABLE public.testtable1(h1 int,h2 char(200),h3 char(200),h4 char(200),h5
    char(200)); CREATE PROCEDURE public.autoInsert() LANGUAGE plpgsql AS $$ declare
    iint; begin i = 1; while i< 5000001 loop insert into public.testtable1 values (i
    ,'hhhh2','hhhh3','hhhh4','hhhh5'); i = i+1; end loop; END$$; call public.
    autoInsert();
    案例1
    會話1
    select count(*) from public.testtable1;
    會話1執行需要5分鐘

    會話2
    drop table public.testtable1;
    會話2被堵塞,會話2鎖類型AccessExclusiveLock被會話1鎖類型AccessShareLock堵塞

    案例2
    會話1
    ALTER TABLE public.testtable1 ADD COLUMN col_1 serial;
    會話1執行需要5分鐘,添加一個自增長的列col_1

    會話2
    select count(*) from public.testtable1;
    會話2被堵塞,會話2鎖類型AccessShareLock被會話1鎖類型AccessExclusiveLock堵塞

    Postgresql結論:
    select堵塞DDL,。
    查詢堵塞的語句:
    select a.locktype,b.datname,a.pid,a.mode,a.granted,regclass(a.relation),
    regclass(a.classid),CASE WHEN granted='f' THEN 'wait_lock' WHEN granted='t' THEN
    'hold_lock' END lock_satus from pg_locks a join pg_database b on a.database=b.
    oid; select * from pg_stat_activity where wait_event_type in ('Lock','LWLock');

    技術
    下載桌面版
    GitHub
    百度網盤(提取碼:draw)
    Gitee
    云服務器優惠
    阿里云優惠券
    騰訊云優惠券
    華為云優惠券
    站點信息
    問題反饋
    郵箱:ixiaoyang8@qq.com
    QQ群:766591547
    關注微信
    巨胸美乳无码人妻视频