pg_reindex 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,22 +1,22 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pg_reindex (0.1.2)
4
+ pg_reindex (0.1.3)
5
5
  pg
6
6
  thor
7
7
 
8
8
  GEM
9
9
  remote: http://rubygems.org/
10
10
  specs:
11
- activemodel (3.2.5)
12
- activesupport (= 3.2.5)
11
+ activemodel (3.2.6)
12
+ activesupport (= 3.2.6)
13
13
  builder (~> 3.0.0)
14
- activerecord (3.2.5)
15
- activemodel (= 3.2.5)
16
- activesupport (= 3.2.5)
14
+ activerecord (3.2.6)
15
+ activemodel (= 3.2.6)
16
+ activesupport (= 3.2.6)
17
17
  arel (~> 3.0.2)
18
18
  tzinfo (~> 0.3.29)
19
- activesupport (3.2.5)
19
+ activesupport (3.2.6)
20
20
  i18n (~> 0.6)
21
21
  multi_json (~> 1.0)
22
22
  arel (3.0.2)
data/README.md CHANGED
@@ -9,10 +9,10 @@ Install:
9
9
 
10
10
  Using:
11
11
 
12
- export PGRE_CFG=/some/path/database.yml
12
+ export PGRE_CFG=/some/path/database.yml
13
13
  pgre --help
14
14
 
15
- User in connection should be an owner of relations. And for rebuild pkey, should be superuser.
15
+ Database.yml from rails application. User in connection settings should be an owner of relations. And for rebuild pkey, should be a superuser.
16
16
 
17
17
  Tasks:
18
18
 
@@ -21,13 +21,16 @@ Tasks:
21
21
  pgre rebuild ENV (table|index)[,(table|index)] # rebuild tables,indexes,pkeys
22
22
  pgre tables ENV # Show tables of database
23
23
 
24
- Examples:
24
+ Use case:
25
+
26
+ # Show databases
27
+ pgre dbs
25
28
 
26
29
  # Show tables with indexes, which full size more than 1Gb
27
30
  pgre tables production -s 1000
28
31
 
29
32
  # Show process without really rebuild
30
- pgre rebuild production users,some_index1,some_index2
33
+ pgre rebuild production users,some_index1
31
34
 
32
35
  # Rebuild indexes
33
36
  pgre rebuild production users --write
@@ -46,8 +49,9 @@ Rebuild index produces sqls:
46
49
  3. DROP INDEX bla;
47
50
  4. ALTER INDEX bla2 RENAME TO bla;
48
51
 
49
- 2 can be blocked by long running query(LRQ), or autovacuum (in this case just kill autovacuum or wait LRQ).
50
- By careful, if between 2 and (3,4) started LRQ or autovacuum, (3,4) can blocks all queries on this table. If this happens, and (3,4) not quit after < 30s, should stop (3,4) by cancel query in PostgreSQL. And execute (3,4) manually.
52
+ 1 can be blocked by long running query(LRQ), or autovacuum (in this case kill autovacuum or wait LRQ).
53
+ **By careful**, if between 1 and (3,4) started LRQ or autovacuum, in this case (3,4) will block all queries on this table.
54
+ If it happens, and (3,4) not quit after < 30s, you should stop (3,4) by cancel query in PostgreSQL, and later execute manually.
51
55
 
52
56
 
53
57
  Rebuild pkey produces sqls:
@@ -56,7 +60,7 @@ Rebuild pkey produces sqls:
56
60
  2. ANALYZE some_table;
57
61
  3. SELECT swap_for_pkey('public', 'some_table_pkey', 'some_table_pkey2');
58
62
 
59
- Same issue with 2 and 3.
63
+ Same issue with 1 and 3.
60
64
 
61
65
 
62
66
  MIT-LICENCE
data/bin/pgre CHANGED
@@ -16,7 +16,7 @@ class PgReindexer < Thor
16
16
  render_db_list(list)
17
17
  end
18
18
 
19
- desc "tables ENV", "Show tables of database"
19
+ desc "tables ENV", "Show tables/indexes for database"
20
20
  method_option :size, :aliases => '-s', :type => :string
21
21
  def tables(env)
22
22
  conn = get_connection(env)
@@ -46,7 +46,7 @@ class PgReindexer < Thor
46
46
  end
47
47
  end
48
48
 
49
- desc "install ENV", "Install need function to database, like function: swap_for_pkey"
49
+ desc "install ENV", "Install function swap_for_pkey to database"
50
50
  def install(env)
51
51
  conn = get_connection(env)
52
52
  conn.install_swap_for_pkey
@@ -111,7 +111,7 @@ private
111
111
  cfg = cfg.sort_by{|a| a[0]}
112
112
  cfg.map do |env, config|
113
113
  x = [env, config]
114
- x << (connection(env).database_size(config['database']) rescue '-') if show_sizes
114
+ x << (connection(env).database_size(config['database']) rescue 'not connected') if show_sizes
115
115
  x
116
116
  end
117
117
  end
@@ -119,7 +119,7 @@ private
119
119
  def do_rebuild(conn, row, write = true, ask = true)
120
120
  #ask = false unless write
121
121
 
122
- say "=> rebuild #{row['index']} (#{row['i_size_p']}), write #{write}, ask #{ask}", :yellow
122
+ say "=> #{row['index']} (#{row['i_size_p']}), write #{write}, ask #{ask}", :yellow
123
123
 
124
124
  sqls = conn.index_sqls(row)
125
125
 
@@ -138,13 +138,23 @@ private
138
138
  end
139
139
  end
140
140
 
141
- if row['index'].end_with?("_pkey")
141
+ if row['primary'] == 't'
142
+ unless conn.have_rebuild_for_relation?('pg_catalog.pg_class')
143
+ say " ... no permission for rebuild pkey, should be superuser\n", :red
144
+ return
145
+ end
146
+
142
147
  unless conn.check_swap_for_pkey
143
- say " ... You should install function swap_for_pkey for rebuild pkey, call: #{$0} install ENV\n", :red
148
+ say " ... install function swap_for_pkey for rebuild pkey, call: #{$0} install ENV\n", :red
144
149
  return
145
150
  end
146
151
  end
147
152
 
153
+ unless conn.have_rebuild_for_relation?(row['table'])
154
+ say " ... no permission for rebuild #{row['table']}, should be an owner or superuser\n", :red
155
+ return
156
+ end
157
+
148
158
  started_at = Time.now
149
159
 
150
160
  if write
@@ -159,7 +169,7 @@ private
159
169
  end
160
170
 
161
171
  new_size = conn.get_index_size(row['index'])['i_size_p'] rescue '-'
162
- say "<= rebuilded #{row['index']} (#{new_size})", :yellow
172
+ say "<= #{row['index']} (#{new_size})", :yellow
163
173
  say " DONE! (#{"%.3f" % (Time.now - started_at)}s)\n", :green
164
174
  else
165
175
  say " DRY-RUN DONE\n", :green
data/lib/pg-reindex.rb CHANGED
@@ -5,10 +5,10 @@ class PgReindex
5
5
  MIN_SIZE = 50 # megabyte min, total table size
6
6
 
7
7
  def initialize(conf)
8
- cfg = {:host => conf['host'] || '127.0.0.1', :dbname => conf['database'],
8
+ @cfg = {:host => conf['host'] || '127.0.0.1', :dbname => conf['database'],
9
9
  :user => conf['username'] || `whoami`.chop, :password => conf['password'] || 'password', :port => conf['port'].to_s}
10
10
 
11
- @conn = PGconn.new cfg
11
+ @conn = PGconn.new @cfg
12
12
  end
13
13
 
14
14
  def get_struct_relations(min_size = nil)
@@ -51,7 +51,8 @@ class PgReindex
51
51
  pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size_p",
52
52
  pg_size_pretty(pg_total_relation_size(C.oid) - pg_relation_size(C.oid)) AS "total_i_size_p",
53
53
  pg_relation_size(i.oid) as "i_size",
54
- pg_size_pretty(pg_relation_size(i.oid)) as "i_size_p"
54
+ pg_size_pretty(pg_relation_size(i.oid)) as "i_size_p",
55
+ ix.indisprimary as "primary"
55
56
  FROM pg_class C, pg_class i, pg_index ix, pg_namespace N
56
57
  WHERE nspname IN ('public') AND
57
58
  C.oid = ix.indrelid and i.oid = ix.indexrelid
@@ -129,17 +130,17 @@ $$language plpgsql;
129
130
  end
130
131
 
131
132
  def index_sqls(index_row)
132
- index_sql_array(index_row['table'], index_row['index_oid'], index_row['index'])
133
+ index_sql_array(index_row['table'], index_row['index_oid'], index_row['index'], index_row['primary'] == 't')
133
134
  end
134
135
 
135
- def index_sql_array(table, oid, name)
136
+ def index_sql_array(table, oid, name, primary = false)
136
137
  new_name = if name.size < 61
137
138
  name + "_2"
138
139
  else
139
140
  name[0..-3] + "_2"
140
141
  end
141
142
 
142
- if name.end_with?('_pkey')
143
+ if primary
143
144
  [
144
145
  index_sql(oid, name, new_name),
145
146
  "ANALYZE #{table}",
@@ -187,7 +188,14 @@ $$language plpgsql;
187
188
  end
188
189
 
189
190
  def cancel(procpid)
190
- @conn.exec "select pg_cancel_backend(#{procpid.to_i})"
191
+ @conn.exec("select pg_cancel_backend(#{procpid.to_i})")
191
192
  end
192
-
193
+
194
+ def have_rebuild_for_relation?(relation)
195
+ res = @conn.exec "select has_table_privilege(E'#{@cfg[:user]}', E'#{relation}', 'update,references')"
196
+ res[0]['has_table_privilege'] == 't' ? true : false
197
+ rescue
198
+ false
199
+ end
200
+
193
201
  end
data/pg_reindex.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{pg_reindex}
5
- s.version = "0.1.2"
5
+ s.version = "0.1.3"
6
6
 
7
7
  s.authors = ["Makarchev Konstantin"]
8
8
 
data/spec/reindex_spec.rb CHANGED
@@ -122,20 +122,28 @@ describe PgReindex do
122
122
  def1 = @pgre.index_def(r['index_oid'])
123
123
 
124
124
  sqls = @pgre.index_sqls(r)
125
- sqls.each do |sql|
126
- @pgre.exec sql
127
- end
125
+ if @pgre.have_rebuild_for_relation?('pg_catalog.pg_class')
126
+ sqls.each do |sql|
127
+ @pgre.exec sql
128
+ end
128
129
 
129
- r2 = row('tests_pkey')
130
- r2['index_oid'].to_i.should > 0
130
+ r2 = row('tests_pkey')
131
+ r2['index_oid'].to_i.should > 0
131
132
 
132
- r2['index_oid'].should == r['index_oid']
133
- def1.should == @pgre.index_def(r2['index_oid'])
133
+ r2['index_oid'].should == r['index_oid']
134
+ def1.should == @pgre.index_def(r2['index_oid'])
134
135
 
135
- # index should be
136
- res = @pgre.filter_relations('tests')
137
- res.size.should == 4
138
- res.map{|el| el['index']}.sort.should == ["a_b_c", "index_tests_on_a", "index_tests_on_b_and_c", "tests_pkey"]
136
+ # index should be
137
+ res = @pgre.filter_relations('tests')
138
+ res.size.should == 4
139
+ res.map{|el| el['index']}.sort.should == ["a_b_c", "index_tests_on_a", "index_tests_on_b_and_c", "tests_pkey"]
140
+ else
141
+ puts "you havn't permission to rebuild pkey, test impossible!"
142
+ end
143
+ end
144
+
145
+ it "have_rebuild_for_relation? should be true for created table" do
146
+ @pgre.have_rebuild_for_relation?('tests').should == true
139
147
  end
140
148
 
141
149
  end
data/spec/spec_support.rb CHANGED
@@ -1,4 +1,4 @@
1
- $cfg = {'adapter' => 'postgresql', 'database' => 'pgre_test', 'encoding' => 'utf8', 'username' => 'kostya', 'password' => 'password'}
1
+ $cfg = {'adapter' => 'postgresql', 'database' => 'pgre_test'}
2
2
  ActiveRecord::Base.establish_connection $cfg
3
3
 
4
4
  class Test < ActiveRecord::Base
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_reindex
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-08 00:00:00.000000000 Z
12
+ date: 2012-06-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -137,3 +137,4 @@ specification_version: 3
137
137
  summary: Console utility for gracefully rebuild indexes/pkeys for PostgreSQL, with
138
138
  minimal locking in semi-auto mode.
139
139
  test_files: []
140
+ has_rdoc: