PostgreSQL创建索引并避免写数据锁定(并发的索引)

关于并发建立索引:http://58.58.27.50:8079/doc/html/9.3.1_zh/sql-createindex.html

写这篇blog源自一个帅哥在建索引发生了表锁的问题。先介绍一下Postgresql的建索引语法: 
Version:9.1

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ name ] ON table [ USING method ]
    ( { column | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
    [ WITH ( storage_parameter = value [, ... ] ) ]
    [ TABLESPACE tablespace ]
    [ WHERE predicate ]

这里不解释语法的诸多参数使用(排序,使用方法,填充因子等),主要说一下concurrently的使用场景。 
  
正常情况下Postgresql建立普通btree索引时会阻塞DML(insert,update,delete)操作,直到索引完成,期间读操作不受阻塞。当只有一个用户操作这当然没问题,但是在生产环境,并发比较高的情况下,特别是大表建索引就不能这么操作了,不然用户要跳起来骂娘了,点个按钮一天还没反应过来。

--使用 
Postgresql提供了一个参数,可以在线建立索引的时候避免因写数据而锁表,这个参数叫concurrently。使用很简单,就是用create index concurrently来代替create index即可。

--副作用 
当然了,使用这个参数是有副作用的,不使用这个参数建索引时DB只扫描一次表,使用这个参数时,会引发DB扫两次表,同时等待所有潜在会读到该索引的事务结束,有点类似增量索引,这么一来,系统的CPU和IO,内存等会受一些影响,所以综合考虑,仍然让用户自行选择,而不是默认。

--失败 
在使用concurrently参数建索引时,有可能会遇到失败的情况,比如建唯一索引索引发现数据有重复,又或者用户发现建索引时建错字段的,取消建索引操作了。此时该表上会存在一个索引,这是因为带这个参数的建索引命令一经发出,就首先会在系统的日志表里先插一个索引记录进去,又因为这个索引最终建失败了,所以会被标记一个INVALID的状态,如下:

postgres=# \d t_kenyon
       Table "public.t_kenyon"
 Column |  Type   | Modifiers 
--------+---------+-----------
 col    | integer | 
Indexes:
    "idx" btree (col) INVALID

--重建 
遇到上述失效的索引重建时两个办法,一个是drop index index_name,然后再执行create index concurrently。还有一个是执行reindex index_name命令,但是后者不支持concurrently参数。

--总结 
在生产上执行创建索引命令时最好带上此参数,因为多消耗一点系统资源和时间来换取用户的不间断访问更新是相对值得的,但是遇到紧急的任务或者超大的表还是要综合考虑。 如果是索引重建,可以再在原基础上建立一个不同名的相同索引,然后取消老的索引。

时间: 2024-10-28 14:18:44

PostgreSQL创建索引并避免写数据锁定(并发的索引)的相关文章

什么是索引?Mysql目前主要的几种索引类型

一.索引MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车. 索引分单列索引和组合索引.单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引.组合索引,即一个索引包含多个列. 创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件). 实际上,索引也是一张表,该表保存了主

Luke 5—— 可视化 Lucene 索引查看工具,可以查看ES的索引

Luke 5 发布,可视化 Lucene 索引查看工具  oschina 发布于2015年08月31日 这是一个主要版本,该版本支持 Lucene 5.2.0. 它支持 elasticsearch 1.6.0(Lucene的4.10.4) 已解决的问题:#20增加支持重建索引并不会存储领域,不暴露位置的字段值. Pull Requests:#23 Elasticsearch 支持和阴影插件组装#26 添加 .gitignore 文件#27 支持 Lucene 5#28 luke.sh 新增LUK

SqlServer 创建聚集索引与非聚集索引处理千万条数据的优化,以及之间的区别

在以下的文章中,我将以"办公自动化"系统为例,探讨如何在有着1000万条数据的MS SQL SERVER数据库中实现快速的数据提取和数据分页.以下代码说明了我们实例中数据库的"红头文件"一表的部分数据结构: CREATE TABLE [dbo].[TGongwen] ( --TGongwen是红头文件表名 [Gid] [int] IDENTITY (1, 1) NOT NULL , --本表的id号,也是主键 [title] [varchar] (80) COLLA

IO流--字符流写数据

IO流是用来处理设备之间的数据传输的,诸如:文件的复制,上传下载文件 Java中的流可以从不同的角度进行分类: - 按照流的方向不同:分为输入流和输出流. - 按照处理数据单位的不同:分为字节流和字符流. - 按照功能不同:分为节点流和处理流 要区分字符流和字节流,我们可以从类名来区分 类名中包含Reader:字符流  输入流 类名中包含Writer:字符流  输出流 类名中包含Input:字节流  输入流 类名中包含Output:字节流  输出流 包含Stream:字节流 今天着重来看下字符流

13.5.1 写数据到 Excel

Excel 的互操作程序集都是标准的 .NET 程序集,我们可以在 F# Interactive 中使用 #r 指令进行引用.引用程序集之后,就能使用类了,既可以把Excel 作为独立(可见或不可见)的应用程序运行,也可以写脚本.清单 13.18 演示了如何启动 Excel,创建有一个工作表的新工作簿,以及把数据写入工作表. 清单13.18 启动 Excel 创建工作表 (F#) #r "office.dll" #r "Microsoft.Office.Interop.Exc

python 使用openpyxl来写数据到excel表格

使用openpyxl写execl确实很方便.我先介绍用到的相关模块与函数 Workbook:工作簿模块,在内存创建一个工作簿. ExcelWriter:使用它向exel中写数据. get_column_letter:给一个数字得到一个列名,如A,B,C 数据写入到EXCEL表格 #!/usr/bin/env python # _*_ coding:utf-8 _*_ from openpyxl.workbook import Workbook from openpyxl.writer.excel

B-树和B+树的应用:数据搜索和数据库索引

B-树 1 .B-树定义 B-树是一种平衡的多路查找树,它在文件系统中很有用. 定义:一棵m 阶的B-树,或者为空树,或为满足下列特性的m 叉树:⑴树中每个结点至多有m 棵子树:⑵若根结点不是叶子结点,则至少有两棵子树: ⑶除根结点之外的所有非终端结点至少有[m/2] 棵子树:⑷所有的非终端结点中包含以下信息数据: (n,A0,K1,A1,K2,-,Kn,An)其中:Ki(i=1,2,-,n)为关键码,且Ki<Ki+1,  Ai 为指向子树根结点的指针(i=0,1,-,n),且指针Ai-1 所指

转:基于B-树和B+树的使用:数据搜索和数据库索引的详细介绍

原文地址:http://www.jb51.net/article/36184.htm B-树 1 .B-树定义 B-树是一种平衡的多路查找树,它在文件系统中很有用. 定义:一棵m 阶的B-树,或者为空树,或为满足下列特性的m 叉树:⑴树中每个结点至多有m 棵子树:⑵若根结点不是叶子结点,则至少有两棵子树: ⑶除根结点之外的所有非终端结点至少有[m/2] 棵子树:⑷所有的非终端结点中包含以下信息数据: (n,A0,K1,A1,K2,-,Kn,An)其中:Ki(i=1,2,-,n)为关键码,且Ki<

sparkStreaming向hbase写数据

在SparkStreaming中统计了数据之后,我们需要将结果写入外部文件系统. 本文,以向Hbase中写数据,为例,说一下,SparkStreaming怎么向Hbase中写数据. 首先,需要说一下,下面的这个方法. foreachRDD(func) 最通用的输出操作,把func作用于从stream生成的每一个RDD. 注意:这个函数是在 运行streaming程序的driver进程 中执行的. 下面跟着思路,看一下,怎么优雅的向Hbase中写入数据 向外部写数据 常见的错误: 向外部数据库写数