免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 8142 | 回复: 16
打印 上一主题 下一主题

Sybase中大的update一定要用小批量(small batch size) - 附例子 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-12-21 05:30 |只看该作者 |倒序浏览
在昨天的回贴中提到大的update一定要用小批量(small batch size),感觉有必要专门发一贴。
Update用Small batch size对高并发的系统相当关键;否则,会造成不良后果,比如:
1、填满logsegment
比如你的logsegment只有2G,需要更改的数据集有10G。即便你更改的数据集没有日志段大,但如果一直hold住syslogs,和其他事务一起也有可能填满日志段,这是为什么后面的例子强调index scan也很关键。

2、阻塞其他进程。如果阻塞发生在关键表上,系统将不可用。
在缺省设置下,更改超过200 rows or pages,行级/页级锁就会升级成表锁而阻塞其他进程读写,详细信息请看lock promotion HWM。
http://infocenter.sybase.com/hel ... /locking/X20061.htm

3、导致out of locks,因为这个进程hold住了locks,其他进程在同一表上的锁不能提升到表锁。
To avoid the overhead of managing hundreds of locks on a table, Adaptive Server uses a lock promotion threshold setting. Once a scan
of a table accumulates more page or row locks than allowed by the lock promotion threshold, Adaptive Server tries to issue a table lock. If it succeeds, the page or row locks are no longer necessary and are released.
When lock promotion is denied due to conflicting locks, a process can accumulate page or row locks in excess of the lock promotion threshold and
may exhaust all available locks in Adaptive Server.

4、导致死锁

5、降低复制系统性能


下面是使用的例子。
1、bcp in
    bcp ...in ..... -b 2000

2、update 最好保证你的update使用 index scan(当然如果涉及80%以上的记录要用表扫描, optimizer considers table scan when 40% of the records are involved)

declare @errorStatus int, @rowsProcessed int

set rowcount 2000

select @rowsProcessed = 1
while (@rowsProcessed != 0)
begin
  begin tran

    update ...
      from ...
     where ...

    select @rowsProcessed = @@rowcount, @errorStatus = @@error

    if (@errorStatus != 0)
    begin
       raiserror ....
       rollback tran
       return -1
    end
  commit tran
end

set rowcount 0






论坛徽章:
0
2 [报告]
发表于 2012-12-21 09:31 |只看该作者
支持大神的分享

论坛徽章:
0
3 [报告]
发表于 2013-01-03 19:18 |只看该作者
总结的很好!其他几点深有体会,第三点,导致 out of locks,有点疑惑。。。sql1 持锁超过200以后,升级为表锁,其他的sql如果需要访问该表,应该是锁等待的状态,这些大量被阻塞的锁,导致锁数目爆掉?

论坛徽章:
0
4 [报告]
发表于 2013-01-07 23:56 |只看该作者
问得非常好!我说反了。如果大批量更改不用small batch size,同时有其他进程在同一表上hold locks,本进程就不能提升到表锁而导致out of locks。用了small batch size就可以让批量更改顺利进行而不会导致serious blocking,for bettter understanding请看一下demand locking和update lock。如果用了小批量还导致serious blocking,可以适当调高lock HWM。

njzh24 发表于 2013-01-03 19:18
总结的很好!其他几点深有体会,第三点,导致 out of locks,有点疑惑。。。sql1 持锁超过200以后,升级为表 ...


论坛徽章:
0
5 [报告]
发表于 2013-01-21 17:18 |只看该作者
感谢楼主指教~

论坛徽章:
7
数据库技术版块每日发帖之星
日期:2015-08-09 06:20:00数据库技术版块每日发帖之星
日期:2015-11-03 06:20:00数据库技术版块每日发帖之星
日期:2016-02-20 06:20:00数据库技术版块每日发帖之星
日期:2016-07-13 06:20:00数据库技术版块每日发帖之星
日期:2016-07-31 06:20:00数据库技术版块每日发帖之星
日期:2016-08-01 06:20:00数据库技术版块每日发帖之星
日期:2016-08-18 06:20:00
6 [报告]
发表于 2013-01-23 02:31 |只看该作者
不过,老大啊,还是有点问题,例如我确实需要在1个tran内update大量数据,拆成一个个小tran的话,如果前面几个tran给commit了,后面发生错误了,尤其是些bug引发的错误,那我这个数据一致性可就没法保证了. 这个如何是好啊?

论坛徽章:
0
7 [报告]
发表于 2013-01-23 23:13 |只看该作者
Eisen 发表于 2013-01-23 02:31
不过,老大啊,还是有点问题,例如我确实需要在1个tran内update大量数据,拆成一个个小tran的话,如果前面几个tr ...


不愧是老江湖,问得好!如果确实需要在1个tran内update大量数据,有两个方法:
* 仍然用小批量,但为了保证事务中途失败能完全回滚,相应表要加一个字段
* 用一个事务更改所有数据,对系统性能有影响,logsegment and tempdb要足够大。

如果一次要更改几千万/上亿条记录,那这两个方法都不行了,各位有没有做过的?先卖个关子。

论坛徽章:
0
8 [报告]
发表于 2013-01-24 15:37 |只看该作者
2BeSybPro 发表于 2013-01-23 23:13
不愧是老江湖,问得好!如果确实需要在1个tran内update大量数据,有两个方法:
* 仍然用小批量,但为了 ...

有什么好方法?请指教!

论坛徽章:
7
数据库技术版块每日发帖之星
日期:2015-08-09 06:20:00数据库技术版块每日发帖之星
日期:2015-11-03 06:20:00数据库技术版块每日发帖之星
日期:2016-02-20 06:20:00数据库技术版块每日发帖之星
日期:2016-07-13 06:20:00数据库技术版块每日发帖之星
日期:2016-07-31 06:20:00数据库技术版块每日发帖之星
日期:2016-08-01 06:20:00数据库技术版块每日发帖之星
日期:2016-08-18 06:20:00
9 [报告]
发表于 2013-01-28 17:46 |只看该作者
我一般会让那些developer们用save tran设置一些节点,不要全部rollback掉.
至于一次修改上亿的,那是没啥好办法了,基本上弄成临时性user table然后使用xcmd shell来bcp 导入一下了,别的好方法还真没想出来.求老大指点.

论坛徽章:
0
10 [报告]
发表于 2013-01-29 00:05 |只看该作者
Eisen 发表于 2013-01-28 17:46
我一般会让那些developer们用save tran设置一些节点,不要全部rollback掉.
至于一次修改上亿的,那是没啥好办 ...


用一个事务的话,没有那么大的logsegment;用小批量的话,要上百个小时;所以时间和空间都不允许。

对超大数据量的更改,最好的方法就是不更改。直接上例子看得明白。

0. expand database if necessary
1. take full dump and turn on "select into/trunc log" option
2. create a new table by "select ... into"

select ... => your updates here
into new_table
from old_table
go
create indexes on new table
go

3. grant privileges for the new table

4. compare the records between old table and new table
   if match
      drop procedures/triggers related to old table
      rename old table
   else
      check the discrepancies

5. rename new table to old table

6. create related procedures/triggers and grant privileges

7. test applications

8. turn off DB options and take full dump to resume log dumps

9. drop the original table one or two weeks later

这个方法适用于Oracle, Sybase and SQL Server。我最先是在Oracle中学到的。
当然上面大数据量更改的方法也可以用于对大数据量的删除;但对于大数据量的删除,小批量仍然是不二法门。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP