KingbaseES运维案例之--- 和 Oracle修改rename表名称对比

案例说明:
KingbaseES 和Oracle数据库同样都支持'alter table xxx rename'的命令来修改表名称,但是当表被select查询时,同时rename表名称的表现却不同。

适用版本:
KingbaseES V8R6

一、KingbaseES数据库测试

1、session A 执行表查询

1)查询表数据(本表数据量较大,查询时间较长)

prod=# select count(*) from t11;
  count
----------
 80000000
(1 row)

2)查看select时锁信息

prod=# SELECT
prod-# a.datname,
prod-# locktype,
prod-# virtualtransaction,
prod-# transactionid,
prod-# nspname,
prod-# relname,
prod-# mode,
prod-# granted,
prod-# cast(date_trunc('second',query_start) AS timestamp) AS query_start
prod-# FROM
prod-# pg_locks
prod-# LEFT OUTER JOIN pg_class ON (pg_locks.relation = pg_class.oid)
prod-# LEFT OUTER JOIN pg_namespace ON (pg_namespace.oid = pg_class.relnamespace),
prod-# pg_stat_activity a
prod-# WHERE NOT pg_locks.pid = pg_backend_pid()
prod-# AND pg_locks.pid=a.pid
prod-# and pg_class.relname='t11';

 datname | locktype | virtualtransaction | transactionid | nspname | relname |      mode       | granted |     qu
ery_start
---------+----------+--------------------+---------------+---------+---------+-----------------+---------+-------
--------------
 prod    | relation | 10/25              |               | public  | t11     | AccessShareLock | t       | 2023-0
9-06 10:27:51
 prod    | relation | 11/1376            |               | public  | t11     | AccessShareLock | t       | 2023-0
9-06 10:27:51
 prod    | relation | 13/109             |               | public  | t11     | AccessShareLock | t       | 2023-0
9-06 10:27:51
(3 rows)

---如上所示,在执行select查询时,会持有‘AccessShareLock’锁。

2、Session B 执行rename table
1)执行rename table(此时表查询仍在继续)

prod=# alter table t11 rename to t1;

---此时rename操作被hang住,需要等待select完成。

2)执行raname table获得的锁信息

prod=# SELECT
prod-# a.datname,
prod-# locktype,
prod-# virtualtransaction,
prod-# transactionid,
prod-# nspname,
prod-# relname,
prod-# mode,
prod-# granted,
prod-# cast(date_trunc('second',query_start) AS timestamp) AS query_start
prod-# FROM
prod-# pg_locks
prod-# LEFT OUTER JOIN pg_class ON (pg_locks.relation = pg_class.oid)
prod-# LEFT OUTER JOIN pg_namespace ON (pg_namespace.oid = pg_class.relnamespace),
prod-# pg_stat_activity a
prod-# WHERE NOT pg_locks.pid = pg_backend_pid()
prod-# AND pg_locks.pid=a.pid
prod-# and pg_class.relname='t11';

 datname | locktype | virtualtransaction | transactionid | nspname | relname |        mode         | granted |
  query_start
---------+----------+--------------------+---------------+---------+---------+---------------------+---------+---
------------------
 prod    | relation | 8/282              |               | public  | t11     | AccessExclusiveLock | f       | 20
23-09-06 10:34:40
 prod    | relation | 10/30              |               | public  | t11     | AccessShareLock     | t       | 20
23-09-06 10:34:18
 prod    | relation | 11/2364            |               | public  | t11     | AccessShareLock     | t       | 20
23-09-06 10:34:18
 prod    | relation | 13/163             |               | public  | t11     | AccessShareLock     | t       | 20
23-09-06 10:34:18
(4 rows)

如下图所示,在执行rename table时,需持有‘AccessExclusiveLock’锁,将和‘AccessShareLock’产生冲突,需要等待‘AccessShareLock ‘锁释放。

二、Oracle 数据库测试

1、session A 执行表查询

1)查询表数据(本表数据量较大,查询时间较长)

15:18:16 SCOTT@prod>select count(*) from t2;

  COUNT(*)
----------
 117440512

2)查看select时锁信息

15:18:10 SYS@prod>r
  1  SELECT S.USERNAME,
  2         L.SID,
  3         TRUNC(l.ID1 / power(2, 16)) rbs,--power(x,y) :计算x^y次方 截断获取高4字节
  4         bitand(l.ID1, to_number('ffff', 'xxxx')) + 0 slot,---bitand 按位与 按位与获取低4字节
  5         l.ID2 seq,
  6         l.LMODE,
  7         l.REQUEST
  8    FROM v$session s, v$lock l
  9   WHERE l.TYPE = 'TX'
 10     AND l.SID = s.SID
 11*    AND s.USERNAME = 'SCOTT'

no rows selected

---如上所示,Oracle在执行select时,不需要持有锁。

2、Session B 执行rename table

1)执行rename table(此时表查询仍在继续)

15:17:20 SCOTT@prod>alter table t2 rename to t1;
Table altered.

---虽然,仍在执行select查询,但是rename table仍然瞬间执行完成,不受select的影响。

三、Kingbase和Oracle锁机制

1、KingbaseES锁机制

如下所示,当用户访问表时,需要对表持有对应的表级锁:

  • ACCESS SHARE(访问共享锁)
    只与ACCESS EXCLUSIVE锁冲突。
    SELECT命令会在当前查询的表上获取一个ACCESS SHARE锁。总的来说,任何只读操作都会获取该锁。
  • ACCESS EXCLUSIVE(访问排他锁)
    和所有的锁都冲突,该锁保证只有持有锁的事务能够访问当前表。
    被DROP TABLE,TRUNCATE,REINDEX,CLUSTER,VACUUM FULL和REFRESH MATERIALIZED VIEW命令自动获取。有很多种形式的ALTER TABLE命令可以获取该锁,它同样也是LOCK TABLE命令默认的锁级别。
    只有ACCESS EXCLUSIVE锁可以防止一个SELECT语句。

2、Oracle 锁机制
如下所示,当Oracle执行不同的操作时,会对访问对象持有对应的锁:

  • DML锁
    DML锁可能是针对某一特定行数据的行级锁,也可能是针对表中所有行的表级锁。当用户拥有DML锁,其他用户不能修改持有锁的数据,也不能修改数据表的结构定义。DML锁主要分为两类:TX锁(事务锁或行级锁)和TM锁(表级锁)。
  • DDL锁
      DDL锁用于保护在执行DDL操作时,对象不会被其他会话修改。在DDL语句执行期间,对象会一直持有DDL锁,执行完成后立即释放。需要注意的是,为了防止阻塞,Oracle中DDL语句一定会(隐式)提交,即使提交失败也是如此,在此之前执行的所有操作都会随之提交。

四、总结
在对表执行查询时,同时执行rename table操作,KingbaseES和Oracle数据库,由于锁机制不同,获取到的结果也不同;对于KingbaseES数据库,在业务繁忙期间,应该避免执行rename table操作,以免产生锁冲突,导致正常的业务访问被阻塞。

五、附件(锁查询语句)

1、kingbase锁查询语句

SELECT
a.datname,
locktype,
virtualtransaction,
transactionid,
nspname,
relname,
mode,
granted,
FROM
pg_locks
LEFT OUTER JOIN pg_class ON (pg_locks.relation = pg_class.oid)
LEFT OUTER JOIN pg_namespace ON (pg_namespace.oid = pg_class.relnamespace),
pg_stat_activity a
WHERE NOT pg_locks.pid = pg_backend_pid()
AND pg_locks.pid=a.pid
and pg_class.relname='t11';

2、Oracle锁查询语句

 SELECT S.USERNAME,
       L.SID,
       TRUNC(l.ID1 / power(2, 16)) rbs,--power(x,y) :计算x^y次方 截断获取高4字节
        bitand(l.ID1, to_number('ffff', 'xxxx')) + 0 slot,---bitand 按位与 按位与获取低4字节
        l.ID2 seq,
       l.LMODE,
       l.REQUEST
       FROM v$session s, v$lock l
       WHERE l.TYPE = 'TX'
        AND l.SID = s.SID
        AND s.USERNAME = 'SCOTT' ;
posted @ 2023-09-06 17:32  天涯客1224  阅读(10)  评论(0编辑  收藏  举报