|
1625 | 1625 | (let [{current-db-version :version} (sutils/db-metadata)] |
1626 | 1626 | (not (neg? (compare current-db-version pg14-db))))) |
1627 | 1627 |
|
| 1628 | +(defn finalize-pending-detach |
| 1629 | + "Finalize a previously failed detach operation. A partitioned table can |
| 1630 | + only have one partition pending detachment at any time." |
| 1631 | + [parent] |
| 1632 | + (let [pending (->> ["SELECT inhrelid::regclass AS child |
| 1633 | + FROM pg_catalog.pg_inherits |
| 1634 | + WHERE inhparent = ?::regclass AND inhdetachpending = true" |
| 1635 | + parent] |
| 1636 | + jdbc/query-to-vec |
| 1637 | + first |
| 1638 | + :child)] |
| 1639 | + (when pending |
| 1640 | + (log/info (trs "Finalizing detach for partition {0}" pending)) |
| 1641 | + (jdbc/do-commands (format "ALTER TABLE %s DETACH PARTITION %s FINALIZE" parent pending)) |
| 1642 | + (str pending)))) |
| 1643 | + |
| 1644 | +(defn find-stranded-partitions |
| 1645 | + "Identify tables that match the child format of a partitioned table (like reports_historical) |
| 1646 | + that are not present in the pg_inherits table. These partitions have been detached, but failed |
| 1647 | + to be deleted. |
| 1648 | +
|
| 1649 | + Tables that are not partitioned will also not be in the pg_inherits table, so you MUST |
| 1650 | + write a child-format that does not match any non-partitioned tables. |
| 1651 | +
|
| 1652 | + Returns a list of strings. Each string is a stranded partition that should be removed." |
| 1653 | + [child-format] |
| 1654 | + (->> [(str "SELECT tablename" |
| 1655 | + " FROM pg_tables WHERE tablename ~ ?" |
| 1656 | + " AND tablename NOT IN (SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits)") |
| 1657 | + child-format] |
| 1658 | + jdbc/query-to-vec |
| 1659 | + (map (comp str :tablename)))) |
| 1660 | + |
1628 | 1661 | (defn prune-daily-partitions |
1629 | 1662 | "Either detaches or drops obsolete day-oriented partitions |
1630 | 1663 | older than the date. Deletes or detaches only the oldest such candidate if |
|
1650 | 1683 | candidates (->> (partitioning/get-partition-names parent-table) |
1651 | 1684 | (filter expired?) |
1652 | 1685 | sort) |
1653 | | - drop-one (fn [table] |
| 1686 | + detach (fn detach [parent child] |
| 1687 | + (jdbc/do-commands-outside-txn |
| 1688 | + (format "alter table %s detach partition %s concurrently" parent child))) |
| 1689 | + drop-one (fn drop-one [table] |
1654 | 1690 | (update-lock-status status-key inc) |
1655 | 1691 | (try! |
1656 | 1692 | (if just-detach? |
1657 | | - (jdbc/do-commands-outside-txn |
1658 | | - (format "alter table %s detach partition %s concurrently" parent-table table)) |
| 1693 | + (let [ex (try |
| 1694 | + (detach parent-table table) |
| 1695 | + (catch SQLException ex |
| 1696 | + (if (= (jdbc/sql-state :not-in-prerequisite-state) (.getSQLState ex)) |
| 1697 | + ex |
| 1698 | + (throw ex))))] |
| 1699 | + (when (instance? SQLException ex) |
| 1700 | + (let [finalized-table (finalize-pending-detach parent-table)] |
| 1701 | + (when-not (= finalized-table table) |
| 1702 | + ;; Retry, unless the finalized partition detach was |
| 1703 | + ;; for the same table |
| 1704 | + (detach parent-table table))))) |
1659 | 1705 | (jdbc/do-commands |
1660 | | - (format "drop table if exists %s cascade" table))) |
| 1706 | + (format "drop table if exists %s cascade" table))) |
1661 | 1707 | (finally |
1662 | 1708 | (update-lock-status status-key dec)))) |
1663 | 1709 | drop #(if incremental? |
|
1697 | 1743 | "Drops the given set of tables. Will throw an SQLException termination if the |
1698 | 1744 | operation takes much longer than PDB_GC_DAILY_PARTITION_DROP_LOCK_TIMEOUT_MS." |
1699 | 1745 | [old-partition-tables update-lock-status status-key] |
1700 | | - (let [drop #(doseq [table old-partition-tables] |
| 1746 | + (let [drop #(doseq [table (distinct old-partition-tables)] |
1701 | 1747 | (try |
1702 | 1748 | (update-lock-status status-key inc) |
1703 | 1749 | (jdbc/do-commands |
|
1720 | 1766 | update-lock-status :write-locking-resource-events)) |
1721 | 1767 | ;; PG14+ |
1722 | 1768 | (let [detached-tables |
1723 | | - (detach-daily-partitions "resource_events_historical" date incremental? |
1724 | | - update-lock-status :write-locking-resource-events)] |
| 1769 | + (detach-daily-partitions "resource_events_historical" date incremental? |
| 1770 | + update-lock-status :write-locking-resource-events) |
| 1771 | + stranded-tables (find-stranded-partitions "^resource_events_\\d\\d\\d\\d\\d\\d\\d\\dz$")] |
1725 | 1772 | (jdbc/with-db-transaction [] |
1726 | | - (drop-partition-tables! detached-tables |
| 1773 | + (drop-partition-tables! (concat detached-tables stranded-tables) |
1727 | 1774 | update-lock-status :write-locking-resource-events))))) |
1728 | 1775 |
|
1729 | 1776 | (defn delete-reports-older-than-in-pg-11! |
|
1767 | 1814 | (detach-daily-partitions "resource_events_historical" effective-resource-events-ttl |
1768 | 1815 | incremental? update-lock-status |
1769 | 1816 | :write-locking-resource-events) |
| 1817 | + stranded-events-tables (find-stranded-partitions "^resource_events_\\d\\d\\d\\d\\d\\d\\d\\dz$") |
1770 | 1818 | detached-report-tables |
1771 | 1819 | (detach-daily-partitions "reports_historical" report-ttl |
1772 | 1820 | incremental? update-lock-status |
1773 | | - :write-locking-reports)] |
| 1821 | + :write-locking-reports) |
| 1822 | + stranded-reports-tables (find-stranded-partitions "^reports_\\d\\d\\d\\d\\d\\d\\d\\dz$")] |
1774 | 1823 | ;; Now we can delete the partitions with less intrusive locking. |
1775 | 1824 | (jdbc/with-db-transaction [] |
1776 | 1825 | ;; Nothing should acquire locks on the detached tables, but to be safe, acquire |
|
1780 | 1829 | ;; force a resource-events GC. prior to partitioning, this would have happened |
1781 | 1830 | ;; via a cascade when the report was deleted, but now we just drop whole tables |
1782 | 1831 | ;; of resource events. |
1783 | | - (drop-partition-tables! detached-resource-event-tables |
| 1832 | + (drop-partition-tables! (concat detached-resource-event-tables stranded-events-tables) |
1784 | 1833 | update-lock-status :write-locking-resource-events) |
1785 | | - (drop-partition-tables! detached-report-tables |
| 1834 | + (drop-partition-tables! (concat detached-report-tables stranded-reports-tables) |
1786 | 1835 | update-lock-status :write-locking-reports)))))) |
1787 | 1836 |
|
1788 | 1837 | ;; A db version that is "allowed" but not supported is deprecated |
|
0 commit comments