pgslice 0.4.3 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +8 -4
- data/lib/pgslice/client.rb +38 -31
- data/lib/pgslice/table.rb +2 -0
- data/lib/pgslice/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b29363ba9973cca9be997f3bc62c748b27bee61d25da67f3d3af60f9166cec9
|
4
|
+
data.tar.gz: bb6be94d05a1ff1e059f3386ce4ba34a1a4698a25f89e676d8d3117d4d203ac4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abceaedcfa90cfa78954c3184baa02e270244d89b4be19016eb0e1c570902008745845018120182f4dbe543a42cf8d6d8926a52238245d95976946fcf1a49d6e
|
7
|
+
data.tar.gz: b5adb37599b3651e737f81193f50495a9ae416544cc96acb77f371c26083cae000c27dc740a9992d303815eb3a250881c7ce5c0dd7bf571e7c1b58f4df4dff66
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -32,7 +32,7 @@ This will give you the `pgslice` command.
|
|
32
32
|
pgslice prep <table> <column> <period>
|
33
33
|
```
|
34
34
|
|
35
|
-
Period can be `day` or `
|
35
|
+
Period can be `day`, `month`, or `year`.
|
36
36
|
|
37
37
|
This creates a table named `<table>_intermediate` with the appropriate trigger for partitioning.
|
38
38
|
|
@@ -98,7 +98,7 @@ BEGIN;
|
|
98
98
|
|
99
99
|
CREATE TABLE visits_intermediate (LIKE visits INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING STORAGE INCLUDING COMMENTS) PARTITION BY RANGE (created_at);
|
100
100
|
|
101
|
-
COMMENT ON TABLE visits_intermediate is 'column:created_at,period:
|
101
|
+
COMMENT ON TABLE visits_intermediate is 'column:created_at,period:month';
|
102
102
|
|
103
103
|
COMMIT;
|
104
104
|
|
@@ -261,7 +261,7 @@ To add partitions, use:
|
|
261
261
|
pgslice add_partitions <table> --future 3
|
262
262
|
```
|
263
263
|
|
264
|
-
Add this as a cron job to create a new partition each day or
|
264
|
+
Add this as a cron job to create a new partition each day, month, or year.
|
265
265
|
|
266
266
|
```sh
|
267
267
|
# day
|
@@ -269,6 +269,9 @@ Add this as a cron job to create a new partition each day or month.
|
|
269
269
|
|
270
270
|
# month
|
271
271
|
0 0 1 * * pgslice add_partitions <table> --future 3 --url ...
|
272
|
+
|
273
|
+
# year
|
274
|
+
0 0 1 1 * pgslice add_partitions <table> --future 3 --url ...
|
272
275
|
```
|
273
276
|
|
274
277
|
Add a monitor to ensure partitions are being created.
|
@@ -283,11 +286,12 @@ WHERE
|
|
283
286
|
n.nspname = 'public' AND
|
284
287
|
c.relname = '<table>_' || to_char(NOW() + INTERVAL '3 days', 'YYYYMMDD')
|
285
288
|
-- for months, use to_char(NOW() + INTERVAL '3 months', 'YYYYMM')
|
289
|
+
-- for years, use to_char(NOW() + INTERVAL '3 years', 'YYYY')
|
286
290
|
```
|
287
291
|
|
288
292
|
## Archiving Partitions
|
289
293
|
|
290
|
-
Back up and drop older partitions each day or
|
294
|
+
Back up and drop older partitions each day, month, or year.
|
291
295
|
|
292
296
|
```sh
|
293
297
|
pg_dump -c -Fc -t <table>_201609 $PGSLICE_URL > <table>_201609.dump
|
data/lib/pgslice/client.rb
CHANGED
@@ -2,8 +2,8 @@ module PgSlice
|
|
2
2
|
class Client < Thor
|
3
3
|
check_unknown_options!
|
4
4
|
|
5
|
-
class_option :url
|
6
|
-
class_option :dry_run, type: :boolean, default: false
|
5
|
+
class_option :url, desc: "Database URL"
|
6
|
+
class_option :dry_run, type: :boolean, default: false, desc: "Print statements without executing"
|
7
7
|
|
8
8
|
map %w[--version -v] => :version
|
9
9
|
|
@@ -13,7 +13,8 @@ module PgSlice
|
|
13
13
|
|
14
14
|
SQL_FORMAT = {
|
15
15
|
day: "YYYYMMDD",
|
16
|
-
month: "YYYYMM"
|
16
|
+
month: "YYYYMM",
|
17
|
+
year: "YYYY"
|
17
18
|
}
|
18
19
|
|
19
20
|
def initialize(*args)
|
@@ -24,10 +25,10 @@ module PgSlice
|
|
24
25
|
end
|
25
26
|
|
26
27
|
desc "prep TABLE [COLUMN] [PERIOD]", "Create an intermediate table for partitioning"
|
27
|
-
option :partition, type: :boolean, default: true
|
28
|
-
option :trigger_based, type: :boolean, default: false
|
28
|
+
option :partition, type: :boolean, default: true, desc: "Partition the table"
|
29
|
+
option :trigger_based, type: :boolean, default: false, desc: "Use trigger-based partitioning"
|
29
30
|
def prep(table, column=nil, period=nil)
|
30
|
-
table =
|
31
|
+
table = qualify_table(table)
|
31
32
|
intermediate_table = table.intermediate_table
|
32
33
|
trigger_name = table.trigger_name
|
33
34
|
|
@@ -102,7 +103,7 @@ COMMENT ON TRIGGER #{quote_ident(trigger_name)} ON #{quote_table(intermediate_ta
|
|
102
103
|
|
103
104
|
desc "unprep TABLE", "Undo prep"
|
104
105
|
def unprep(table)
|
105
|
-
table =
|
106
|
+
table = qualify_table(table)
|
106
107
|
intermediate_table = table.intermediate_table
|
107
108
|
trigger_name = table.trigger_name
|
108
109
|
|
@@ -116,11 +117,11 @@ COMMENT ON TRIGGER #{quote_ident(trigger_name)} ON #{quote_table(intermediate_ta
|
|
116
117
|
end
|
117
118
|
|
118
119
|
desc "add_partitions TABLE", "Add partitions"
|
119
|
-
option :intermediate, type: :boolean, default: false
|
120
|
-
option :past, type: :numeric, default: 0
|
121
|
-
option :future, type: :numeric, default: 0
|
120
|
+
option :intermediate, type: :boolean, default: false, desc: "Add to intermediate table"
|
121
|
+
option :past, type: :numeric, default: 0, desc: "Number of past partitions to add"
|
122
|
+
option :future, type: :numeric, default: 0, desc: "Number of future partitions to add"
|
122
123
|
def add_partitions(table)
|
123
|
-
original_table =
|
124
|
+
original_table = qualify_table(table)
|
124
125
|
table = options[:intermediate] ? original_table.intermediate_table : original_table
|
125
126
|
trigger_name = original_table.trigger_name
|
126
127
|
|
@@ -245,17 +246,17 @@ CREATE OR REPLACE FUNCTION #{quote_ident(trigger_name)}()
|
|
245
246
|
end
|
246
247
|
|
247
248
|
desc "fill TABLE", "Fill the partitions in batches"
|
248
|
-
option :batch_size, type: :numeric, default: 10000
|
249
|
-
option :swapped, type: :boolean, default: false
|
250
|
-
option :source_table
|
251
|
-
option :dest_table
|
252
|
-
option :start
|
253
|
-
option :where
|
254
|
-
option :sleep, type: :numeric
|
249
|
+
option :batch_size, type: :numeric, default: 10000, desc: "Batch size"
|
250
|
+
option :swapped, type: :boolean, default: false, desc: "Use swapped table"
|
251
|
+
option :source_table, desc: "Source table"
|
252
|
+
option :dest_table, desc: "Destination table"
|
253
|
+
option :start, type: :numeric, desc: "Primary key to start"
|
254
|
+
option :where, desc: "Conditions to filter"
|
255
|
+
option :sleep, type: :numeric, desc: "Seconds to sleep between batches"
|
255
256
|
def fill(table)
|
256
|
-
table =
|
257
|
-
source_table =
|
258
|
-
dest_table =
|
257
|
+
table = qualify_table(table)
|
258
|
+
source_table = qualify_table(options[:source_table]) if options[:source_table]
|
259
|
+
dest_table = qualify_table(options[:dest_table]) if options[:dest_table]
|
259
260
|
|
260
261
|
if options[:swapped]
|
261
262
|
source_table ||= table.retired_table
|
@@ -345,9 +346,9 @@ INSERT INTO #{quote_table(dest_table)} (#{fields})
|
|
345
346
|
end
|
346
347
|
|
347
348
|
desc "swap TABLE", "Swap the intermediate table with the original table"
|
348
|
-
option :lock_timeout, default: "5s"
|
349
|
+
option :lock_timeout, default: "5s", desc: "Lock timeout"
|
349
350
|
def swap(table)
|
350
|
-
table =
|
351
|
+
table = qualify_table(table)
|
351
352
|
intermediate_table = table.intermediate_table
|
352
353
|
retired_table = table.retired_table
|
353
354
|
|
@@ -371,7 +372,7 @@ INSERT INTO #{quote_table(dest_table)} (#{fields})
|
|
371
372
|
|
372
373
|
desc "unswap TABLE", "Undo swap"
|
373
374
|
def unswap(table)
|
374
|
-
table =
|
375
|
+
table = qualify_table(table)
|
375
376
|
intermediate_table = table.intermediate_table
|
376
377
|
retired_table = table.retired_table
|
377
378
|
|
@@ -392,9 +393,9 @@ INSERT INTO #{quote_table(dest_table)} (#{fields})
|
|
392
393
|
end
|
393
394
|
|
394
395
|
desc "analyze TABLE", "Analyze tables"
|
395
|
-
option :swapped, type: :boolean, default: false
|
396
|
+
option :swapped, type: :boolean, default: false, desc: "Use swapped table"
|
396
397
|
def analyze(table)
|
397
|
-
table =
|
398
|
+
table = qualify_table(table)
|
398
399
|
parent_table = options[:swapped] ? table : table.intermediate_table
|
399
400
|
|
400
401
|
existing_tables = table.existing_partitions
|
@@ -502,8 +503,10 @@ INSERT INTO #{quote_table(dest_table)} (#{fields})
|
|
502
503
|
case period.to_sym
|
503
504
|
when :day
|
504
505
|
"%Y%m%d"
|
505
|
-
|
506
|
+
when :month
|
506
507
|
"%Y%m"
|
508
|
+
else
|
509
|
+
"%Y"
|
507
510
|
end
|
508
511
|
end
|
509
512
|
|
@@ -512,8 +515,10 @@ INSERT INTO #{quote_table(dest_table)} (#{fields})
|
|
512
515
|
case period.to_sym
|
513
516
|
when :day
|
514
517
|
date
|
515
|
-
|
518
|
+
when :month
|
516
519
|
Date.new(date.year, date.month)
|
520
|
+
else
|
521
|
+
Date.new(date.year)
|
517
522
|
end
|
518
523
|
end
|
519
524
|
|
@@ -522,8 +527,10 @@ INSERT INTO #{quote_table(dest_table)} (#{fields})
|
|
522
527
|
case period.to_sym
|
523
528
|
when :day
|
524
529
|
date.next_day(count)
|
525
|
-
|
530
|
+
when :month
|
526
531
|
date.next_month(count)
|
532
|
+
else
|
533
|
+
date.next_year(count)
|
527
534
|
end
|
528
535
|
end
|
529
536
|
|
@@ -540,7 +547,7 @@ INSERT INTO #{quote_table(dest_table)} (#{fields})
|
|
540
547
|
end
|
541
548
|
|
542
549
|
def qualify_table(table)
|
543
|
-
table.to_s.include?(".") ? table : [schema, table].join(".")
|
550
|
+
Table.new(table.to_s.include?(".") ? table : [schema, table].join("."))
|
544
551
|
end
|
545
552
|
|
546
553
|
def settings_from_trigger(original_table, table)
|
@@ -555,7 +562,7 @@ INSERT INTO #{quote_table(dest_table)} (#{fields})
|
|
555
562
|
|
556
563
|
unless period
|
557
564
|
needs_comment = true
|
558
|
-
function_def = execute("
|
565
|
+
function_def = execute("SELECT pg_get_functiondef(oid) FROM pg_proc WHERE proname = $1", [trigger_name])[0]
|
559
566
|
return [] unless function_def
|
560
567
|
function_def = function_def["pg_get_functiondef"]
|
561
568
|
sql_format = SQL_FORMAT.find { |_, f| function_def.include?("'#{f}'") }
|
data/lib/pgslice/table.rb
CHANGED
data/lib/pgslice/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pgslice
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|