我们应该使用 read-committed 隔离级别吗?
should we use read-committed isolation level?
我有一个名为 "radacct" 的 mysql innodb table。 table 包含用户互联网使用记录,如上传、下载、帐户 ID 等(table 架构如下)。 radacct
table 随机更新路由器发送的数据。我们也使用这个table来计算互联网用户的总带宽,带宽计算查询(select)大约需要3-4秒。当带宽计算查询和来自路由器竞争锁的更新查询并发执行时,就会出现问题。这是由于 Repeatable 读取锁(table 级别锁定)并且最好在此处使用 ReadCommitted 隔离吗?
describe freeradius.radacct;
+----------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+-------------+------+-----+---------+----------------+
| radacctid | bigint(21) | NO | PRI | NULL | auto_increment |
| acctsessionid | varchar(32) | NO | MUL | | |
| acctuniqueid | varchar(32) | NO | MUL | | |
| username | varchar(64) | NO | MUL | | |
| groupname | varchar(64) | NO | | | |
| realm | varchar(64) | YES | | | |
| nasipaddress | varchar(15) | NO | MUL | | |
| nasportid | varchar(15) | YES | | NULL | |
| nasporttype | varchar(32) | YES | | NULL | |
| acctstarttime | datetime | YES | MUL | NULL | |
| acctstoptime | datetime | YES | MUL | NULL | |
| acctsessiontime | int(12) | YES | MUL | NULL | |
| acctauthentic | varchar(32) | YES | | NULL | |
| connectinfo_start | varchar(50) | YES | | NULL | |
| connectinfo_stop | varchar(50) | YES | | NULL | |
| acctinputoctets | bigint(20) | YES | | NULL | |
| acctoutputoctets | bigint(20) | YES | | NULL | |
| calledstationid | varchar(50) | NO | | | |
| callingstationid | varchar(50) | NO | | | |
| acctterminatecause | varchar(32) | NO | | | |
| servicetype | varchar(32) | YES | | NULL | |
| framedprotocol | varchar(32) | YES | | NULL | |
| framedipaddress | varchar(15) | NO | MUL | | |
| acctstartdelay | int(12) | YES | | NULL | |
| acctstopdelay | int(12) | YES | | NULL | |
| xascendsessionsvrkey | varchar(10) | YES | | NULL | |
+----------------------+-------------+------+-----+---------+----------------+
mysql> show session variables like '%isol%';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)
带宽计算查询
SELECT sum(acctinputoctets),sum(acctoutputoctets) from radacct
where username='davidjohnsoon' and acctstarttime
between '2015-10-11 14:10:17' and '2016-08-22 14:53:00'
Insert/Update 在 mysql> show full processlist;
上看到的查询
INSERT INTO radacct (acctsessionid, acctuniqueid, username, realm, nasipaddress, nasportid, nasporttype, acctstarttime, acctstoptime,acctsessiontime, acctauthentic, connectinfo_start, connectinfo_stop, acctinputoctets, acctoutputoctets, calledstationid, callingstationid, acctterminatecause,servicetype, framedprotocol, framedipaddress, acctstartdelay, acctstopdelay)
VALUES ('260204248', 'a5b889ad247a514b', 'johnson', '','100.44.44.44', '297797794', 'Ethernet', DATE_SUB('2016-08-23 13:02:50',INTERVAL (1 + 0) SECOND), '2016-08-23 13:02:50', '1', 'RADIUS', '', '', '0' << 32 | '0', '0' << 32 | '0','','90:61:0c:1a:94:96','User-Error','Framed-User', 'PPP', '','0', '0')
RC 和 RR 的区别是:select结果在一次交易中是否会改变;
所以在RR中,如果发生更新查询,结果不会在一个事务中发生变化;
RR 中的示例:
会话 1:10:00:00- 开启交易;
会话 1:10:00:00-执行带宽计算查询;
session 1: 10:00:08-完成带宽计算查询,result=100;
会话 2:10:00:05-更新查询;
会话 1:10:00:09-执行带宽计算查询;
session 1: 10:00:17-完成带宽计算查询,result=100;
会话 1:10:00:18- 结束事务;
但是使用 RC,示例中的第二个带宽计算查询将得到不同的结果,may 101;
如果在执行带宽计算查询时执行了更新查询,则没有任何变化;
我的看法:
在这种情况下,RC和RR都可以;
我有一个名为 "radacct" 的 mysql innodb table。 table 包含用户互联网使用记录,如上传、下载、帐户 ID 等(table 架构如下)。 radacct
table 随机更新路由器发送的数据。我们也使用这个table来计算互联网用户的总带宽,带宽计算查询(select)大约需要3-4秒。当带宽计算查询和来自路由器竞争锁的更新查询并发执行时,就会出现问题。这是由于 Repeatable 读取锁(table 级别锁定)并且最好在此处使用 ReadCommitted 隔离吗?
describe freeradius.radacct;
+----------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+-------------+------+-----+---------+----------------+
| radacctid | bigint(21) | NO | PRI | NULL | auto_increment |
| acctsessionid | varchar(32) | NO | MUL | | |
| acctuniqueid | varchar(32) | NO | MUL | | |
| username | varchar(64) | NO | MUL | | |
| groupname | varchar(64) | NO | | | |
| realm | varchar(64) | YES | | | |
| nasipaddress | varchar(15) | NO | MUL | | |
| nasportid | varchar(15) | YES | | NULL | |
| nasporttype | varchar(32) | YES | | NULL | |
| acctstarttime | datetime | YES | MUL | NULL | |
| acctstoptime | datetime | YES | MUL | NULL | |
| acctsessiontime | int(12) | YES | MUL | NULL | |
| acctauthentic | varchar(32) | YES | | NULL | |
| connectinfo_start | varchar(50) | YES | | NULL | |
| connectinfo_stop | varchar(50) | YES | | NULL | |
| acctinputoctets | bigint(20) | YES | | NULL | |
| acctoutputoctets | bigint(20) | YES | | NULL | |
| calledstationid | varchar(50) | NO | | | |
| callingstationid | varchar(50) | NO | | | |
| acctterminatecause | varchar(32) | NO | | | |
| servicetype | varchar(32) | YES | | NULL | |
| framedprotocol | varchar(32) | YES | | NULL | |
| framedipaddress | varchar(15) | NO | MUL | | |
| acctstartdelay | int(12) | YES | | NULL | |
| acctstopdelay | int(12) | YES | | NULL | |
| xascendsessionsvrkey | varchar(10) | YES | | NULL | |
+----------------------+-------------+------+-----+---------+----------------+
mysql> show session variables like '%isol%';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)
带宽计算查询
SELECT sum(acctinputoctets),sum(acctoutputoctets) from radacct
where username='davidjohnsoon' and acctstarttime
between '2015-10-11 14:10:17' and '2016-08-22 14:53:00'
Insert/Update 在 mysql> show full processlist;
INSERT INTO radacct (acctsessionid, acctuniqueid, username, realm, nasipaddress, nasportid, nasporttype, acctstarttime, acctstoptime,acctsessiontime, acctauthentic, connectinfo_start, connectinfo_stop, acctinputoctets, acctoutputoctets, calledstationid, callingstationid, acctterminatecause,servicetype, framedprotocol, framedipaddress, acctstartdelay, acctstopdelay)
VALUES ('260204248', 'a5b889ad247a514b', 'johnson', '','100.44.44.44', '297797794', 'Ethernet', DATE_SUB('2016-08-23 13:02:50',INTERVAL (1 + 0) SECOND), '2016-08-23 13:02:50', '1', 'RADIUS', '', '', '0' << 32 | '0', '0' << 32 | '0','','90:61:0c:1a:94:96','User-Error','Framed-User', 'PPP', '','0', '0')
RC 和 RR 的区别是:select结果在一次交易中是否会改变;
所以在RR中,如果发生更新查询,结果不会在一个事务中发生变化;
RR 中的示例:
会话 1:10:00:00- 开启交易;
会话 1:10:00:00-执行带宽计算查询;
session 1: 10:00:08-完成带宽计算查询,result=100;
会话 2:10:00:05-更新查询;
会话 1:10:00:09-执行带宽计算查询;
session 1: 10:00:17-完成带宽计算查询,result=100;
会话 1:10:00:18- 结束事务;
但是使用 RC,示例中的第二个带宽计算查询将得到不同的结果,may 101;
如果在执行带宽计算查询时执行了更新查询,则没有任何变化;
我的看法: 在这种情况下,RC和RR都可以;