lib/pgsync/task.rb in pgsync-0.6.1 vs lib/pgsync/task.rb in pgsync-0.6.2
- old
+ new
@@ -273,19 +273,29 @@
raise Error, "Single column primary key required for this data rule: #{rule}" unless primary_key.size == 1
"#{quoted_table}.#{quote_ident(primary_key.first)}"
end
def maybe_disable_triggers
- if opts[:disable_integrity] || opts[:disable_user_triggers]
+ if opts[:disable_integrity] || opts[:disable_integrity_v2] || opts[:disable_user_triggers]
destination.transaction do
triggers = destination.triggers(table)
triggers.select! { |t| t["enabled"] == "t" }
internal_triggers, user_triggers = triggers.partition { |t| t["internal"] == "t" }
integrity_triggers = internal_triggers.select { |t| t["integrity"] == "t" }
restore_triggers = []
- if opts[:disable_integrity]
+ # both --disable-integrity options require superuser privileges
+ # however, only v2 works on Amazon RDS, which added specific support for it
+ # https://aws.amazon.com/about-aws/whats-new/2014/11/10/amazon-rds-postgresql-read-replicas/
+ #
+ # session_replication_role disables more than foreign keys (like triggers and rules)
+ # this is probably fine, but keep the current default for now
+ if opts[:disable_integrity_v2] || (opts[:disable_integrity] && rds?)
+ # SET LOCAL lasts until the end of the transaction
+ # https://www.postgresql.org/docs/current/sql-set.html
+ destination.execute("SET LOCAL session_replication_role = replica")
+ elsif opts[:disable_integrity]
integrity_triggers.each do |trigger|
destination.execute("ALTER TABLE #{quoted_table} DISABLE TRIGGER #{quote_ident(trigger["name"])}")
end
restore_triggers.concat(integrity_triggers)
end
@@ -308,8 +318,12 @@
result
end
else
yield
end
+ end
+
+ def rds?
+ destination.execute("SELECT name, setting FROM pg_settings WHERE name LIKE 'rds.%'").any?
end
end
end