0s autopkgtest [11:37:39]: starting date and time: 2025-01-06 11:37:39+0000 0s autopkgtest [11:37:39]: git checkout: 325255d2 Merge branch 'pin-any-arch' into 'ubuntu/production' 0s autopkgtest [11:37:39]: host juju-7f2275-prod-proposed-migration-environment-20; command line: /home/ubuntu/autopkgtest/runner/autopkgtest --output-dir /tmp/autopkgtest-work.n58m_641/out --timeout-copy=6000 --setup-commands /home/ubuntu/autopkgtest-cloud/worker-config-production/setup-canonical.sh --apt-pocket=proposed=src:postgresql-17,src:icu --apt-upgrade slony1-2 --timeout-short=300 --timeout-copy=20000 --timeout-build=20000 '--env=ADT_TEST_TRIGGERS=postgresql-17/17.2-1build2 icu/76.1-1ubuntu1' -- ssh -s /home/ubuntu/autopkgtest/ssh-setup/nova -- --flavor autopkgtest-ppc64el --security-groups autopkgtest-juju-7f2275-prod-proposed-migration-environment-20@bos03-ppc64el-7.secgroup --name adt-plucky-ppc64el-slony1-2-20250106-113738-juju-7f2275-prod-proposed-migration-environment-20-c781bbe5-9201-4e22-b3fd-a94884e1d410 --image adt/ubuntu-plucky-ppc64el-server --keyname testbed-juju-7f2275-prod-proposed-migration-environment-20 --net-id=net_prod-proposed-migration-ppc64el -e TERM=linux -e ''"'"'http_proxy=http://squid.internal:3128'"'"'' -e ''"'"'https_proxy=http://squid.internal:3128'"'"'' -e ''"'"'no_proxy=127.0.0.1,127.0.1.1,login.ubuntu.com,localhost,localdomain,novalocal,internal,archive.ubuntu.com,ports.ubuntu.com,security.ubuntu.com,ddebs.ubuntu.com,changelogs.ubuntu.com,keyserver.ubuntu.com,launchpadlibrarian.net,launchpadcontent.net,launchpad.net,10.24.0.0/24,keystone.ps5.canonical.com,objectstorage.prodstack5.canonical.com,radosgw.ps5.canonical.com'"'"'' --mirror=http://ftpmaster.internal/ubuntu/ 424s nova [W] Using flock in prodstack6-ppc64el 424s Creating nova instance adt-plucky-ppc64el-slony1-2-20250106-113738-juju-7f2275-prod-proposed-migration-environment-20-c781bbe5-9201-4e22-b3fd-a94884e1d410 from image adt/ubuntu-plucky-ppc64el-server-20250106.img (UUID 66818982-bc25-4f66-80f3-4b4ddeb5bc55)... 424s nova [E] nova boot failed (attempt #0): 424s nova [E] DEBUG (extension:189) found extension EntryPoint.parse('v1password = swiftclient.authv1:PasswordLoader') 424s DEBUG (extension:189) found extension EntryPoint.parse('noauth = cinderclient.contrib.noauth:CinderNoAuthLoader') 424s DEBUG (extension:189) found extension EntryPoint.parse('admin_token = keystoneauth1.loading._plugins.admin_token:AdminToken') 424s DEBUG (extension:189) found extension EntryPoint.parse('none = keystoneauth1.loading._plugins.noauth:NoAuth') 424s DEBUG (extension:189) found extension EntryPoint.parse('password = keystoneauth1.loading._plugins.identity.generic:Password') 424s DEBUG (extension:189) found extension EntryPoint.parse('token = keystoneauth1.loading._plugins.identity.generic:Token') 424s DEBUG (extension:189) found extension EntryPoint.parse('v2password = keystoneauth1.loading._plugins.identity.v2:Password') 424s DEBUG (extension:189) found extension EntryPoint.parse('v2token = keystoneauth1.loading._plugins.identity.v2:Token') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3adfspassword = keystoneauth1.extras._saml2._loading:ADFSPassword') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3applicationcredential = keystoneauth1.loading._plugins.identity.v3:ApplicationCredential') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3fedkerb = keystoneauth1.extras.kerberos._loading:MappedKerberos') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3kerberos = keystoneauth1.extras.kerberos._loading:Kerberos') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3multifactor = keystoneauth1.loading._plugins.identity.v3:MultiFactor') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3oauth1 = keystoneauth1.extras.oauth1._loading:V3OAuth1') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3oidcaccesstoken = keystoneauth1.loading._plugins.identity.v3:OpenIDConnectAccessToken') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3oidcauthcode = keystoneauth1.loading._plugins.identity.v3:OpenIDConnectAuthorizationCode') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3oidcclientcredentials = keystoneauth1.loading._plugins.identity.v3:OpenIDConnectClientCredentials') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3oidcpassword = keystoneauth1.loading._plugins.identity.v3:OpenIDConnectPassword') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3password = keystoneauth1.loading._plugins.identity.v3:Password') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3samlpassword = keystoneauth1.extras._saml2._loading:Saml2Password') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3token = keystoneauth1.loading._plugins.identity.v3:Token') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3tokenlessauth = keystoneauth1.loading._plugins.identity.v3:TokenlessAuth') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3totp = keystoneauth1.loading._plugins.identity.v3:TOTP') 424s DEBUG (session:517) REQ: curl -g -i -X GET https://keystone.ps6.canonical.com:5000/v3 -H "Accept: application/json" -H "User-Agent: nova keystoneauth1/4.0.0 python-requests/2.22.0 CPython/3.8.10" 424s DEBUG (connectionpool:962) Starting new HTTPS connection (1): keystone.ps6.canonical.com:5000 424s DEBUG (connectionpool:429) https://keystone.ps6.canonical.com:5000 "GET /v3 HTTP/1.1" 200 267 424s DEBUG (session:548) RESP: [200] Connection: Keep-Alive Content-Length: 267 Content-Type: application/json Date: Mon, 06 Jan 2025 11:38:50 GMT Keep-Alive: timeout=75, max=1000 Server: Apache/2.4.52 (Ubuntu) Vary: X-Auth-Token x-openstack-request-id: req-98e74c8e-fbcb-46c1-92d9-616738a2f182 424s DEBUG (session:580) RESP BODY: {"version": {"id": "v3.14", "status": "stable", "updated": "2020-04-07T00:00:00Z", "links": [{"rel": "self", "href": "https://keystone.ps6.canonical.com:5000/v3/"}], "media-types": [{"base": "application/json", "type": "application/vnd.openstack.identity-v3+json"}]}} 424s DEBUG (session:946) GET call to https://keystone.ps6.canonical.com:5000/v3 used request id req-98e74c8e-fbcb-46c1-92d9-616738a2f182 424s DEBUG (base:182) Making authentication request to https://keystone.ps6.canonical.com:5000/v3/auth/tokens 424s DEBUG (connectionpool:429) https://keystone.ps6.canonical.com:5000 "POST /v3/auth/tokens HTTP/1.1" 201 12525 424s DEBUG (base:187) {"token": {"methods": ["password"], "user": {"domain": {"id": "default", "name": "Default"}, "id": "c871debdeffd4cb8b69ce618fc4aa361", "name": "prod-proposed-migration-ppc64el", "password_expires_at": null}, "audit_ids": ["iKhOWd9RSI-N3abJ43rt9Q"], "expires_at": "2025-01-07T11:38:50.000000Z", "issued_at": "2025-01-06T11:38:50.000000Z", "project": {"domain": {"id": "default", "name": "Default"}, "id": "623df63b80274c21bc79a0c35e68d615", "name": "prod-proposed-migration-ppc64el_project"}, "is_domain": false, "roles": [{"id": "80674fb26dab46e9a6bd57e7f8193360", "name": "load-balancer_member"}, {"id": "86bf3043974746c2bf52c2a9f362f986", "name": "reader"}, {"id": "15cf997650e345b7b21c02b5cdb7d84a", "name": "member"}], "is_admin_project": false, "catalog": [{"endpoints": [{"id": "213cdf38198c4581bd5b7d6d0836923b", "interface": "internal", "region_id": "prodstack6", "url": "https://radosgw-internal.ps6.canonical.com:443/", "region": "prodstack6"}, {"id": "67061eee26944a1a8009f9d07be19738", "interface": "public", "region_id": "prodstack6", "url": "https://radosgw.ps6.canonical.com:443/", "region": "prodstack6"}, {"id": "fc88c52c749a47d08a24a2c7efbde01b", "interface": "admin", "region_id": "prodstack6", "url": "https://radosgw-admin.ps6.canonical.com:443/", "region": "prodstack6"}], "id": "06e4714942634054bf9aa11715312b4e", "type": "s3", "name": "s3"}, {"endpoints": [{"id": "8aa44c94b63746bd9b37f1008ad55fa8", "interface": "admin", "region_id": "prodstack6", "url": "https://aodh-admin.ps6.canonical.com:8042", "region": "prodstack6"}, {"id": "92cf08a80a0242ebbca8ec893cf332b1", "interface": "public", "region_id": "prodstack6", "url": "https://aodh.ps6.canonical.com:8042", "region": "prodstack6"}, {"id": "d8139c6e11ae4edcb78981c12bd53212", "interface": "internal", "region_id": "prodstack6", "url": "https://aodh-internal.ps6.canonical.com:8042", "region": "prodstack6"}], "id": "2fb939b0b969435c8f0c5fa4edb4de94", "type": "alarming", "name": "aodh"}, {"endpoints": [{"id": "a49fcc80e658411885f88cdd8432a571", "interface": "internal", "region_id": "prodstack6", "url": "https://heat-internal.ps6.canonical.com:8000/v1", "region": "prodstack6"}, {"id": "b23866fddba8415885b06c064c34b94b", "interface": "public", "region_id": "prodstack6", "url": "https://heat.ps6.canonical.com:8000/v1", "region": "prodstack6"}, {"id": "f84ae55197f94b8392a678f35c82ca26", "interface": "admin", "region_id": "prodstack6", "url": "https://heat-admin.ps6.canonical.com:8000/v1", "region": "prodstack6"}], "id": "3d4b59f7dab644b2b527e8e96b697545", "type": "cloudformation", "name": "heat-cfn"}, {"endpoints": [{"id": "2e0143334c6241169f45f1c11970c6bc", "interface": "public", "region_id": "prodstack6", "url": "https://heat.ps6.canonical.com:8004/v1/623df63b80274c21bc79a0c35e68d615", "region": "prodstack6"}, {"id": "5e19c32243c04a3faf1e5f9ab900c260", "interface": "internal", "region_id": "prodstack6", "url": "https://heat-internal.ps6.canonical.com:8004/v1/623df63b80274c21bc79a0c35e68d615", "region": "prodstack6"}, {"id": "b3fc5c88ec8543a691fec75726b86967", "interface": "admin", "region_id": "prodstack6", "url": "https://heat-admin.ps6.canonical.com:8004/v1/623df63b80274c21bc79a0c35e68d615", "region": "prodstack6"}], "id": "43b926205044476b8093b18d8ce0a9e4", "type": "orchestration", "name": "heat"}, {"endpoints": [{"id": "a47569b96e5b4146a312e4673504557c", "interface": "public", "region_id": "prodstack6", "url": "https://glance.ps6.canonical.com:9292", "region": "prodstack6"}, {"id": "bba35c4ab04f4114a2a34e65568537bd", "interface": "internal", "region_id": "prodstack6", "url": "https://glance-internal.ps6.canonical.com:9292", "region": "prodstack6"}, {"id": "ef769f1117c74a62a279131486c89628", "interface": "admin", "region_id": "prodstack6", "url": "https://glance-admin.ps6.canonical.com:9292", "region": "prodstack6"}], "id": "49de724549524bd78e9cd46a4477226f", "type": "image", "name": "glance"}, {"endpoints": [{"id": "a1a41e9a1e2d42e5b6cd5380cd1e21bf", "interface": "admin", "region_id": "prodstack6", "url": "https://cinder-admin.ps6.canonical.com:8776/v3/623df63b80274c21bc79a0c35e68d615", "region": "prodstack6"}, {"id": "d2309a99724b4111827482c68a832c0c", "interface": "public", "region_id": "prodstack6", "url": "https://cinder.ps6.canonical.com:8776/v3/623df63b80274c21bc79a0c35e68d615", "region": "prodstack6"}, {"id": "f8a02e3949ff42afa772eb5e74dbef9f", "interface": "internal", "region_id": "prodstack6", "url": "https://cinder-internal.ps6.canonical.com:8776/v3/623df63b80274c21bc79a0c35e68d615", "region": "prodstack6"}], "id": "5bf6578a631349e3af4bf36d7adb18e1", "type": "volumev3", "name": "cinderv3"}, {"endpoints": [{"id": "01d84128f36444e9b01549b86bd69116", "interface": "admin", "region_id": "prodstack6", "url": "https://barbican-admin.ps6.canonical.com:9312", "region": "prodstack6"}, {"id": "0ce4a8777e0b40a88f7fc0f77e34a605", "interface": "public", "region_id": "prodstack6", "url": "https://barbican.ps6.canonical.com:9311", "region": "prodstack6"}, {"id": "f507ba49e4a7435cb330234217c92449", "interface": "internal", "region_id": "prodstack6", "url": "https://barbican-internal.ps6.canonical.com:9311", "region": "prodstack6"}], "id": "62cb1c3d9f6c45979c13516a6b3ff114", "type": "key-manager", "name": "barbican"}, {"endpoints": [{"id": "3cb6121bd8f14da8aa2fba7be823a2b4", "interface": "internal", "region_id": "prodstack6", "url": "https://neutron-internal.ps6.canonical.com:9696", "region": "prodstack6"}, {"id": "46ba11d133fe4e8f9e8f9097ba737682", "interface": "admin", "region_id": "prodstack6", "url": "https://neutron-admin.ps6.canonical.com:9696", "region": "prodstack6"}, {"id": "d872eb6aa23d40009165aa3dcdce3948", "interface": "public", "region_id": "prodstack6", "url": "https://neutron.ps6.canonical.com:9696", "region": "prodstack6"}], "id": "759cb6fdfbc146dd8b9d1ba444c4b9db", "type": "network", "name": "neutron"}, {"endpoints": [{"id": "4349d565f72446da9699269f85df5e8b", "interface": "internal", "region_id": "prodstack6", "url": "https://manila-internal.ps6.canonical.com:8786/v2/623df63b80274c21bc79a0c35e68d615", "region": "prodstack6"}, {"id": "a483dcc58f5e415e9ec739c94474e609", "interface": "public", "region_id": "prodstack6", "url": "https://manila.ps6.canonical.com:8786/v2/623df63b80274c21bc79a0c35e68d615", "region": "prodstack6"}, {"id": "c1f14236723e42878562d8dd63d5a6a0", "interface": "admin", "region_id": "prodstack6", "url": "https://manila-admin.ps6.canonical.com:8786/v2/623df63b80274c21bc79a0c35e68d615", "region": "prodstack6"}], "id": "93fc4008035946deb1f433c2dd905a5d", "type": "sharev2", "name": "manilav2"}, {"endpoints": [{"id": "0fa148793c7249c8b187b6b4ff425731", "interface": "internal", "region_id": "prodstack6", "url": "https://radosgw-internal.ps6.canonical.com:443/swift/v1/AUTH_e4b04ca58d734ed0aa29e306adad4f79/simplestreams/data", "region": "prodstack6"}, {"id": "555ade266a6b4bcc81b6e5abf607aec5", "interface": "public", "region_id": "prodstack6", "url": "https://radosgw.ps6.canonical.com:443/swift/v1/AUTH_e4b04ca58d734ed0aa29e306adad4f79/simplestreams/data", "region": "prodstack6"}, {"id": "7dad1a7b1552465686424fc014463173", "interface": "admin", "region_id": "prodstack6", "url": "https://radosgw-admin.ps6.canonical.com:443/swift/simplestreams/data", "region": "prodstack6"}], "id": "977dd359af1a4fcc91a9daf4dc33b0f3", "type": "product-streams", "name": "image-stream"}, {"endpoints": [{"id": "12d30eabcdec4831bd15273d55b1cbab", "interface": "internal", "region_id": "prodstack6", "url": "https://manila-internal.ps6.canonical.com:8786/v1/623df63b80274c21bc79a0c35e68d615", "region": "prodstack6"}, {"id": "29d35b2b483346479f1ff1a13604d50e", "interface": "admin", "region_id": "prodstack6", "url": "https://manila-admin.ps6.canonical.com:8786/v1/623df63b80274c21bc79a0c35e68d615", "region": "prodstack6"}, {"id": "4aa1422b8f5945d8aed9ba6a8d670e5c", "interface": "public", "region_id": "prodstack6", "url": "https://manila.ps6.canonical.com:8786/v1/623df63b80274c21bc79a0c35e68d615", "region": "prodstack6"}], "id": "ac5e4f28fa794cde99f1d7ffc1b664e5", "type": "share", "name": "manila"}, {"endpoints": [{"id": "c7db93d54a684d8caeae1d9e18a59118", "interface": "admin", "region_id": "prodstack6", "url": "https://nova-admin.ps6.canonical.com:8774/v2.1", "region": "prodstack6"}, {"id": "dd7a796f401b477f9f1b5bbc05747d8d", "interface": "public", "region_id": "prodstack6", "url": "https://nova.ps6.canonical.com:8774/v2.1", "region": "prodstack6"}, {"id": "e7ecb038d830462ea67b0b463af5e013", "interface": "internal", "region_id": "prodstack6", "url": "https://nova-internal.ps6.canonical.com:8774/v2.1", "region": "prodstack6"}], "id": "b4519af08e174d4a8333a2d14ac3ba3b", "type": "compute", "name": "nova"}, {"endpoints": [{"id": "02ef5b6154934ffd97d8b5b8e4d70d2a", "interface": "internal", "region_id": "prodstack6", "url": "https://radosgw-internal.ps6.canonical.com:443/swift/v1/AUTH_623df63b80274c21bc79a0c35e68d615", "region": "prodstack6"}, {"id": "2741abe526e94842a4fa801423ba1ef0", "interface": "public", "region_id": "prodstack6", "url": "https://radosgw.ps6.canonical.com:443/swift/v1/AUTH_623df63b80274c21bc79a0c35e68d615", "region": "prodstack6"}, {"id": "3742f9406c604516933d6fd8c29e0880", "interface": "admin", "region_id": "prodstack6", "url": "https://radosgw-admin.ps6.canonical.com:443/swift", "region": "prodstack6"}], "id": "c7f07a7b3b3c408c96200dfd1d1a0f6f", "type": "object-store", "name": "swift"}, {"endpoints": [{"id": "06d4ed6c160a43f2b7fa7f80ad1dc709", "interface": "internal", "region_id": "prodstack6", "url": "https://designate-internal.ps6.canonical.com:9001", "region": "prodstack6"}, {"id": "1e240624a50c4ca0aaa6ef63cbc94f1b", "interface": "admin", "region_id": "prodstack6", "url": "https://designate-admin.ps6.canonical.com:9001", "region": "prodstack6"}, {"id": "f94d7d17997a43fd9c63b34c43301c6e", "interface": "public", "region_id": "prodstack6", "url": "https://designate.ps6.canonical.com:9001", "region": "prodstack6"}], "id": "cf82013d63844fedbe96bcacb6bd1fef", "type": "dns", "name": "designate"}, {"endpoints": [{"id": "4a688340be464710bfa60bf3f88f41c4", "interface": "admin", "region_id": "prodstack6", "url": "https://gnocchi-admin.ps6.canonical.com:8041", "region": "prodstack6"}, {"id": "a5a95506c96d4716adb4efc3ac9051be", "interface": "public", "region_id": "prodstack6", "url": "https://gnocchi.ps6.canonical.com:8041", "region": "prodstack6"}, {"id": "eebc17a086834f8fa8bb6b35c8061a8c", "interface": "internal", "region_id": "prodstack6", "url": "https://gnocchi-internal.ps6.canonical.com:8041", "region": "prodstack6"}], "id": "d10589e854a446a5b852593f33f170a7", "type": "metric", "name": "gnocchi"}, {"endpoints": [{"id": "08f66df28d0f47f3bec12f29e06d85ac", "interface": "admin", "region_id": "prodstack6", "url": "https://keystone-admin.ps6.canonical.com:35357/v3", "region": "prodstack6"}, {"id": "46d270b45ceb42db902f4d241afa6a70", "interface": "public", "region_id": "prodstack6", "url": "https://keystone.ps6.canonical.com:5000/v3", "region": "prodstack6"}, {"id": "a4addee11d9349cfa46ec6660dbad947", "interface": "internal", "region_id": "prodstack6", "url": "https://keystone-internal.ps6.canonical.com:5000/v3", "region": "prodstack6"}], "id": "deb38a775a9b4e87a8de9e3eed779882", "type": "identity", "name": "keystone"}, {"endpoints": [{"id": "18b4af5f40664babb94e884c6a53ccf3", "interface": "admin", "region_id": "prodstack6", "url": "https://octavia-admin.ps6.canonical.com:9876", "region": "prodstack6"}, {"id": "2b6f7ba7f9944ee1aebd6dccc5223b2d", "interface": "internal", "region_id": "prodstack6", "url": "https://octavia-internal.ps6.canonical.com:9876", "region": "prodstack6"}, {"id": "5e3012e9c79e4890be4d964b6208f5c6", "interface": "public", "region_id": "prodstack6", "url": "https://octavia.ps6.canonical.com:9876", "region": "prodstack6"}], "id": "e00337be20d54948b66a1c3109b885c6", "type": "load-balancer", "name": "octavia"}, {"endpoints": [{"id": "2d2942b35f3041389ad810f679d02f22", "interface": "public", "region_id": "prodstack6", "url": "https://placement.ps6.canonical.com:8778", "region": "prodstack6"}, {"id": "2e3beaac7ac14284b72e2592820ad725", "interface": "admin", "region_id": "prodstack6", "url": "https://placement-admin.ps6.canonical.com:8778", "region": "prodstack6"}, {"id": "91060f6df9ae444f81808adf40540d94", "interface": "internal", "region_id": "prodstack6", "url": "https://placement-internal.ps6.canonical.com:8778", "region": "prodstack6"}], "id": "edc6e37f154f4c0ab3dd4d52b82bf873", "type": "placement", "name": "placement"}]}} 424s REQ: curl -g -i -X GET https://nova.ps6.canonical.com:8774/v2.1 -H "Accept: application/json" -H "User-Agent: python-novaclient" -H "X-Auth-Token: {SHA256}bd8ed50138f633602170b409961fbe057d2ef70333a865d83dbeb4f375266907" 424s DEBUG (session:517) REQ: curl -g -i -X GET https://nova.ps6.canonical.com:8774/v2.1 -H "Accept: application/json" -H "User-Agent: python-novaclient" -H "X-Auth-Token: {SHA256}bd8ed50138f633602170b409961fbe057d2ef70333a865d83dbeb4f375266907" 424s DEBUG (connectionpool:962) Starting new HTTPS connection (1): nova.ps6.canonical.com:8774 424s DEBUG (connectionpool:429) https://nova.ps6.canonical.com:8774 "GET /v2.1 HTTP/1.1" 302 0 424s RESP: [302] Connection: Keep-Alive Content-Length: 0 Content-Type: text/plain; charset=utf8 Date: Mon, 06 Jan 2025 11:38:51 GMT Keep-Alive: timeout=75, max=1000 Location: https://nova.ps6.canonical.com:8774/v2.1/ Server: Apache/2.4.52 (Ubuntu) x-compute-request-id: req-954342df-37c5-47d9-9dfd-f3f730fe5926 x-openstack-request-id: req-954342df-37c5-47d9-9dfd-f3f730fe5926 424s DEBUG (session:548) RESP: [302] Connection: Keep-Alive Content-Length: 0 Content-Type: text/plain; charset=utf8 Date: Mon, 06 Jan 2025 11:38:51 GMT Keep-Alive: timeout=75, max=1000 Location: https://nova.ps6.canonical.com:8774/v2.1/ Server: Apache/2.4.52 (Ubuntu) x-compute-request-id: req-954342df-37c5-47d9-9dfd-f3f730fe5926 x-openstack-request-id: req-954342df-37c5-47d9-9dfd-f3f730fe5926 424s RESP BODY: Omitted, Content-Type is set to text/plain; charset=utf8. Only application/json responses have their bodies logged. 424s DEBUG (session:580) RESP BODY: Omitted, Content-Type is set to text/plain; charset=utf8. Only application/json responses have their bodies logged. 424s DEBUG (connectionpool:429) https://nova.ps6.canonical.com:8774 "GET /v2.1/ HTTP/1.1" 200 397 424s RESP: [200] Connection: Keep-Alive Content-Length: 397 Content-Type: application/json Date: Mon, 06 Jan 2025 11:38:51 GMT Keep-Alive: timeout=75, max=999 OpenStack-API-Version: compute 2.1 Server: Apache/2.4.52 (Ubuntu) Vary: OpenStack-API-Version,X-OpenStack-Nova-API-Version X-OpenStack-Nova-API-Version: 2.1 x-compute-request-id: req-ac09a0a5-47c5-4f14-b572-013cb79be020 x-openstack-request-id: req-ac09a0a5-47c5-4f14-b572-013cb79be020 424s DEBUG (session:548) RESP: [200] Connection: Keep-Alive Content-Length: 397 Content-Type: application/json Date: Mon, 06 Jan 2025 11:38:51 GMT Keep-Alive: timeout=75, max=999 OpenStack-API-Version: compute 2.1 Server: Apache/2.4.52 (Ubuntu) Vary: OpenStack-API-Version,X-OpenStack-Nova-API-Version X-OpenStack-Nova-API-Version: 2.1 x-compute-request-id: req-ac09a0a5-47c5-4f14-b572-013cb79be020 x-openstack-request-id: req-ac09a0a5-47c5-4f14-b572-013cb79be020 424s RESP BODY: {"version": {"id": "v2.1", "status": "CURRENT", "version": "2.90", "min_version": "2.1", "updated": "2013-07-23T11:33:21Z", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/"}, {"rel": "describedby", "type": "text/html", "href": "http://docs.openstack.org/"}], "media-types": [{"base": "application/json", "type": "application/vnd.openstack.compute+json;version=2.1"}]}} 424s DEBUG (session:580) RESP BODY: {"version": {"id": "v2.1", "status": "CURRENT", "version": "2.90", "min_version": "2.1", "updated": "2013-07-23T11:33:21Z", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/"}, {"rel": "describedby", "type": "text/html", "href": "http://docs.openstack.org/"}], "media-types": [{"base": "application/json", "type": "application/vnd.openstack.compute+json;version=2.1"}]}} 424s GET call to compute for https://nova.ps6.canonical.com:8774/v2.1/ used request id req-ac09a0a5-47c5-4f14-b572-013cb79be020 424s DEBUG (session:936) GET call to compute for https://nova.ps6.canonical.com:8774/v2.1/ used request id req-ac09a0a5-47c5-4f14-b572-013cb79be020 424s DEBUG (extension:189) found extension EntryPoint.parse('v1password = swiftclient.authv1:PasswordLoader') 424s DEBUG (extension:189) found extension EntryPoint.parse('noauth = cinderclient.contrib.noauth:CinderNoAuthLoader') 424s DEBUG (extension:189) found extension EntryPoint.parse('admin_token = keystoneauth1.loading._plugins.admin_token:AdminToken') 424s DEBUG (extension:189) found extension EntryPoint.parse('none = keystoneauth1.loading._plugins.noauth:NoAuth') 424s DEBUG (extension:189) found extension EntryPoint.parse('password = keystoneauth1.loading._plugins.identity.generic:Password') 424s DEBUG (extension:189) found extension EntryPoint.parse('token = keystoneauth1.loading._plugins.identity.generic:Token') 424s DEBUG (extension:189) found extension EntryPoint.parse('v2password = keystoneauth1.loading._plugins.identity.v2:Password') 424s DEBUG (extension:189) found extension EntryPoint.parse('v2token = keystoneauth1.loading._plugins.identity.v2:Token') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3adfspassword = keystoneauth1.extras._saml2._loading:ADFSPassword') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3applicationcredential = keystoneauth1.loading._plugins.identity.v3:ApplicationCredential') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3fedkerb = keystoneauth1.extras.kerberos._loading:MappedKerberos') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3kerberos = keystoneauth1.extras.kerberos._loading:Kerberos') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3multifactor = keystoneauth1.loading._plugins.identity.v3:MultiFactor') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3oauth1 = keystoneauth1.extras.oauth1._loading:V3OAuth1') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3oidcaccesstoken = keystoneauth1.loading._plugins.identity.v3:OpenIDConnectAccessToken') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3oidcauthcode = keystoneauth1.loading._plugins.identity.v3:OpenIDConnectAuthorizationCode') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3oidcclientcredentials = keystoneauth1.loading._plugins.identity.v3:OpenIDConnectClientCredentials') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3oidcpassword = keystoneauth1.loading._plugins.identity.v3:OpenIDConnectPassword') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3password = keystoneauth1.loading._plugins.identity.v3:Password') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3samlpassword = keystoneauth1.extras._saml2._loading:Saml2Password') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3token = keystoneauth1.loading._plugins.identity.v3:Token') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3tokenlessauth = keystoneauth1.loading._plugins.identity.v3:TokenlessAuth') 424s DEBUG (extension:189) found extension EntryPoint.parse('v3totp = keystoneauth1.loading._plugins.identity.v3:TOTP') 424s DEBUG (session:517) REQ: curl -g -i -X GET https://glance.ps6.canonical.com:9292/v2/images/66818982-bc25-4f66-80f3-4b4ddeb5bc55 -H "Accept: application/json" -H "OpenStack-API-Version: compute 2.87" -H "User-Agent: python-novaclient" -H "X-Auth-Token: {SHA256}bd8ed50138f633602170b409961fbe057d2ef70333a865d83dbeb4f375266907" -H "X-OpenStack-Nova-API-Version: 2.87" 424s DEBUG (connectionpool:962) Starting new HTTPS connection (1): glance.ps6.canonical.com:9292 424s DEBUG (connectionpool:429) https://glance.ps6.canonical.com:9292 "GET /v2/images/66818982-bc25-4f66-80f3-4b4ddeb5bc55 HTTP/1.1" 200 2294 424s DEBUG (session:548) RESP: [200] Connection: Keep-Alive Content-Length: 2294 Content-Type: application/json Date: Mon, 06 Jan 2025 11:38:51 GMT Keep-Alive: timeout=75, max=1000 Server: Apache/2.4.52 (Ubuntu) X-Openstack-Request-Id: req-36004257-ff95-41ae-9db0-1b8cb8e39902 424s DEBUG (session:580) RESP BODY: {"architecture": "ppc64le", "base_image_ref": "93404c41-3be3-4a13-b02b-2a1e42399530", "boot_roles": "member,load-balancer_member,reader", "content_id": "auto.sync", "hw_cdrom_bus": "scsi", "hw_disk_bus": "virtio", "hw_machine_type": "pseries", "hw_video_model": "vga", "hw_vif_model": "virtio", "image_location": "snapshot", "image_state": "available", "image_type": "snapshot", "instance_uuid": "aad2dc82-443a-4c50-8705-11e717de8820", "item_name": "disk1.img", "os_distro": "ubuntu", "os_version": "25.04", "owner_id": "623df63b80274c21bc79a0c35e68d615", "owner_project_name": "prod-proposed-migration-ppc64el_project", "owner_user_name": "prod-proposed-migration-ppc64el", "product_name": "com.ubuntu.cloud.daily:server:25.04:ppc64el", "simplestreams_metadata": "{\"aliases\": \"25.04,p,plucky,devel\", \"arch\": \"ppc64el\", \"ftype\": \"disk1.img\", \"label\": \"daily\", \"md5\": \"ba08164f86d9d01e6f74c296e51f14d5\", \"os\": \"ubuntu\", \"pubname\": \"ubuntu-plucky-daily-ppc64el-server-20241215\", \"release\": \"plucky\", \"release_codename\": \"P", "source_content_id": "com.ubuntu.cloud:daily:download", "user_id": "c871debdeffd4cb8b69ce618fc4aa361", "version_name": "20241215", "name": "adt/ubuntu-plucky-ppc64el-server-20250106.img", "disk_format": "qcow2", "container_format": "bare", "visibility": "private", "size": 2718105600, "virtual_size": 21474836480, "status": "active", "checksum": "242e65660b61000980b64fef466c760c", "protected": false, "min_ram": 0, "min_disk": 20, "owner": "623df63b80274c21bc79a0c35e68d615", "os_hidden": false, "os_hash_algo": "sha512", "os_hash_value": "9e613a3d3079e982fbc0fee10f1f39f79fe37d8b1bdb338aca18f78f940868942bf6e68500bbd7a319d5eb547e9ce89f2a17755dc4d6bbc6a08fb821d76ac5a2", "id": "66818982-bc25-4f66-80f3-4b4ddeb5bc55", "created_at": "2025-01-06T02:14:41Z", "updated_at": "2025-01-06T02:15:10Z", "locations": [{"url": "rbd://eea9d068-c18c-11ed-8dc0-013aacb71b80/glance/66818982-bc25-4f66-80f3-4b4ddeb5bc55/snap", "metadata": {"store": "ceph"}}], "direct_url": "rbd://eea9d068-c18c-11ed-8dc0-013aacb71b80/glance/66818982-bc25-4f66-80f3-4b4ddeb5bc55/snap", "tags": [], "self": "/v2/images/66818982-bc25-4f66-80f3-4b4ddeb5bc55", "file": "/v2/images/66818982-bc25-4f66-80f3-4b4ddeb5bc55/file", "schema": "/v2/schemas/image", "stores": "ceph"} 424s DEBUG (session:936) GET call to image for https://glance.ps6.canonical.com:9292/v2/images/66818982-bc25-4f66-80f3-4b4ddeb5bc55 used request id req-36004257-ff95-41ae-9db0-1b8cb8e39902 424s DEBUG (session:517) REQ: curl -g -i -X GET https://nova.ps6.canonical.com:8774/v2.1/flavors/autopkgtest-ppc64el -H "Accept: application/json" -H "OpenStack-API-Version: compute 2.87" -H "User-Agent: python-novaclient" -H "X-Auth-Token: {SHA256}bd8ed50138f633602170b409961fbe057d2ef70333a865d83dbeb4f375266907" -H "X-OpenStack-Nova-API-Version: 2.87" 424s DEBUG (connectionpool:429) https://nova.ps6.canonical.com:8774 "GET /v2.1/flavors/autopkgtest-ppc64el HTTP/1.1" 404 92 424s DEBUG (session:548) RESP: [404] Connection: Keep-Alive Content-Length: 92 Content-Type: application/json; charset=UTF-8 Date: Mon, 06 Jan 2025 11:38:51 GMT Keep-Alive: timeout=75, max=998 OpenStack-API-Version: compute 2.87 Server: Apache/2.4.52 (Ubuntu) Vary: OpenStack-API-Version,X-OpenStack-Nova-API-Version X-OpenStack-Nova-API-Version: 2.87 x-compute-request-id: req-cc73c120-1f5d-4d86-8d56-d48b20c38a33 x-openstack-request-id: req-cc73c120-1f5d-4d86-8d56-d48b20c38a33 424s DEBUG (session:580) RESP BODY: {"itemNotFound": {"code": 404, "message": "Flavor autopkgtest-ppc64el could not be found."}} 424s DEBUG (session:936) GET call to compute for https://nova.ps6.canonical.com:8774/v2.1/flavors/autopkgtest-ppc64el used request id req-cc73c120-1f5d-4d86-8d56-d48b20c38a33 424s DEBUG (session:517) REQ: curl -g -i -X GET https://nova.ps6.canonical.com:8774/v2.1/flavors?is_public=None -H "Accept: application/json" -H "OpenStack-API-Version: compute 2.87" -H "User-Agent: python-novaclient" -H "X-Auth-Token: {SHA256}bd8ed50138f633602170b409961fbe057d2ef70333a865d83dbeb4f375266907" -H "X-OpenStack-Nova-API-Version: 2.87" 424s DEBUG (connectionpool:429) https://nova.ps6.canonical.com:8774 "GET /v2.1/flavors?is_public=None HTTP/1.1" 200 39839 424s DEBUG (session:548) RESP: [200] Connection: Keep-Alive Content-Length: 39839 Content-Type: application/json Date: Mon, 06 Jan 2025 11:38:51 GMT Keep-Alive: timeout=75, max=997 OpenStack-API-Version: compute 2.87 Server: Apache/2.4.52 (Ubuntu) Vary: OpenStack-API-Version,X-OpenStack-Nova-API-Version X-OpenStack-Nova-API-Version: 2.87 x-compute-request-id: req-b5b97936-a63f-4f85-92ec-5d7885cc1f50 x-openstack-request-id: req-b5b97936-a63f-4f85-92ec-5d7885cc1f50 424s DEBUG (session:580) RESP BODY: {"flavors": [{"id": "05338e57-e2ba-4813-9a8a-2f2af73f8ab2", "name": "builder-ppc64el-cpu2-ram4-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/05338e57-e2ba-4813-9a8a-2f2af73f8ab2"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/05338e57-e2ba-4813-9a8a-2f2af73f8ab2"}], "description": null}, {"id": "08090b4b-98a9-4c15-8ad4-cc6711700879", "name": "builder-ppc64el-cpu8-ram64-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/08090b4b-98a9-4c15-8ad4-cc6711700879"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/08090b4b-98a9-4c15-8ad4-cc6711700879"}], "description": null}, {"id": "0825b8b1-2b9c-42bf-b3e6-e827c22d8df5", "name": "builder-ppc64el-cpu8-ram4-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/0825b8b1-2b9c-42bf-b3e6-e827c22d8df5"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/0825b8b1-2b9c-42bf-b3e6-e827c22d8df5"}], "description": null}, {"id": "0b06db45-151e-44b2-b0f5-f069ad7fa1cb", "name": "builder-ppc64el-cpu2-ram12-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/0b06db45-151e-44b2-b0f5-f069ad7fa1cb"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/0b06db45-151e-44b2-b0f5-f069ad7fa1cb"}], "description": null}, {"id": "0dbf127e-3101-4f05-9d37-15ad6d2a45c1", "name": "builder-ppc64el-cpu2-ram16-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/0dbf127e-3101-4f05-9d37-15ad6d2a45c1"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/0dbf127e-3101-4f05-9d37-15ad6d2a45c1"}], "description": null}, {"id": "102d0b57-e8d2-46c6-9be4-f452119a0280", "name": "autopkgtest-ppc64el", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/102d0b57-e8d2-46c6-9be4-f452119a0280"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/102d0b57-e8d2-46c6-9be4-f452119a0280"}], "description": null}, {"id": "1219f5f0-83f3-4d33-a3bb-1a85c6303159", "name": "builder-ppc64el-cpu128-ram64-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/1219f5f0-83f3-4d33-a3bb-1a85c6303159"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/1219f5f0-83f3-4d33-a3bb-1a85c6303159"}], "description": null}, {"id": "1359c5a4-ee60-4855-9bcc-defd3bff7121", "name": "builder-ppc64el-cpu8-ram8-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/1359c5a4-ee60-4855-9bcc-defd3bff7121"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/1359c5a4-ee60-4855-9bcc-defd3bff7121"}], "description": null}, {"id": "161f21bc-11f7-4ec9-a322-04fc3e0d2a68", "name": "builder-ppc64el-cpu2-ram55-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/161f21bc-11f7-4ec9-a322-04fc3e0d2a68"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/161f21bc-11f7-4ec9-a322-04fc3e0d2a68"}], "description": null}, {"id": "166070cd-7110-473e-a6a2-5e25aa9eeefd", "name": "builder-ppc64el-cpu4-ram64-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/166070cd-7110-473e-a6a2-5e25aa9eeefd"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/166070cd-7110-473e-a6a2-5e25aa9eeefd"}], "description": null}, {"id": "16a0a259-4627-4fbd-bb9d-a3e69346467c", "name": "builder-ppc64el-cpu8-ram64-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/16a0a259-4627-4fbd-bb9d-a3e69346467c"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/16a0a259-4627-4fbd-bb9d-a3e69346467c"}], "description": null}, {"id": "1c59e50a-1a67-4691-8f2c-6954cb0f83ba", "name": "builder-ppc64el-cpu4-ram128-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/1c59e50a-1a67-4691-8f2c-6954cb0f83ba"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/1c59e50a-1a67-4691-8f2c-6954cb0f83ba"}], "description": null}, {"id": "1c94efa8-905a-4bff-8485-0aaf9ac47fe7", "name": "builder-ppc64el-cpu4-ram16-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/1c94efa8-905a-4bff-8485-0aaf9ac47fe7"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/1c94efa8-905a-4bff-8485-0aaf9ac47fe7"}], "description": null}, {"id": "213c954d-26ed-4c86-9592-66384bc22c82", "name": "builder-ppc64el-cpu4-ram16-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/213c954d-26ed-4c86-9592-66384bc22c82"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/213c954d-26ed-4c86-9592-66384bc22c82"}], "description": null}, {"id": "219e90b4-8850-4fa4-b028-4cf7657c3264", "name": "builder-ppc64el-cpu16-ram64-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/219e90b4-8850-4fa4-b028-4cf7657c3264"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/219e90b4-8850-4fa4-b028-4cf7657c3264"}], "description": null}, {"id": "21de1f2a-7ad2-4da5-b6af-de683afb51c9", "name": "builder-ppc64el-cpu48-ram64-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/21de1f2a-7ad2-4da5-b6af-de683afb51c9"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/21de1f2a-7ad2-4da5-b6af-de683afb51c9"}], "description": null}, {"id": "2363173d-a2e1-4383-945f-d69f583a729a", "name": "builder-ppc64el-cpu128-ram128-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/2363173d-a2e1-4383-945f-d69f583a729a"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/2363173d-a2e1-4383-945f-d69f583a729a"}], "description": null}, {"id": "23b7a6d6-425f-4669-961d-be7fed7725d3", "name": "builder-ppc64el-cpu2-ram12-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/23b7a6d6-425f-4669-961d-be7fed7725d3"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/23b7a6d6-425f-4669-961d-be7fed7725d3"}], "description": null}, {"id": "2464732a-3147-40fb-b375-2d275070a1f3", "name": "builder-ppc64el-cpu2-ram64-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/2464732a-3147-40fb-b375-2d275070a1f3"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/2464732a-3147-40fb-b375-2d275070a1f3"}], "description": null}, {"id": "250ba167-175c-4548-be23-47a517fa3701", "name": "builder-ppc64el-cpu16-ram72-disk80", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/250ba167-175c-4548-be23-47a517fa3701"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/250ba167-175c-4548-be23-47a517fa3701"}], "description": null}, {"id": "27ffca72-b7d0-4d4b-96c6-de69e0f767bd", "name": "builder-ppc64el-cpu2-ram8-disk1500", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/27ffca72-b7d0-4d4b-96c6-de69e0f767bd"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/27ffca72-b7d0-4d4b-96c6-de69e0f767bd"}], "description": null}, {"id": "2b2e94dd-a11d-4eae-93df-c8cce920b95e", "name": "builder-ppc64el-cpu2-ram32-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/2b2e94dd-a11d-4eae-93df-c8cce920b95e"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/2b2e94dd-a11d-4eae-93df-c8cce920b95e"}], "description": null}, {"id": "2d842f6f-be4f-4b39-bc9e-a8dbf3233bc1", "name": "builder-ppc64el-cpu2-ram4-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/2d842f6f-be4f-4b39-bc9e-a8dbf3233bc1"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/2d842f6f-be4f-4b39-bc9e-a8dbf3233bc1"}], "description": null}, {"id": "2f626a91-24b0-44ba-afa5-2cab984ae81f", "name": "builder-ppc64el-cpu128-ram32-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/2f626a91-24b0-44ba-afa5-2cab984ae81f"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/2f626a91-24b0-44ba-afa5-2cab984ae81f"}], "description": null}, {"id": "3325f74a-e433-4072-8c2c-b50052e31602", "name": "builder-ppc64el-cpu2-ram8-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/3325f74a-e433-4072-8c2c-b50052e31602"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/3325f74a-e433-4072-8c2c-b50052e31602"}], "description": null}, {"id": "34df8936-a2ae-450a-9fea-2cdaebae5803", "name": "builder-ppc64el-cpu8-ram16-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/34df8936-a2ae-450a-9fea-2cdaebae5803"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/34df8936-a2ae-450a-9fea-2cdaebae5803"}], "description": null}, {"id": "378080cb-1d08-401a-b556-0f903a79ae2c", "name": "builder-ppc64el-cpu8-ram12-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/378080cb-1d08-401a-b556-0f903a79ae2c"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/378080cb-1d08-401a-b556-0f903a79ae2c"}], "description": null}, {"id": "37ed4cfe-a588-40c4-8494-098403c1f0f3", "name": "builder-ppc64el-cpu4-ram12-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/37ed4cfe-a588-40c4-8494-098403c1f0f3"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/37ed4cfe-a588-40c4-8494-098403c1f0f3"}], "description": null}, {"id": "3aa7a161-3310-40b9-8e89-195294d45b10", "name": "builder-ppc64el-cpu48-ram128-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/3aa7a161-3310-40b9-8e89-195294d45b10"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/3aa7a161-3310-40b9-8e89-195294d45b10"}], "description": null}, {"id": "3c30219d-30a4-4fb4-bf2e-da5602313583", "name": "builder-ppc64el-cpu2-ram32-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/3c30219d-30a4-4fb4-bf2e-da5602313583"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/3c30219d-30a4-4fb4-bf2e-da5602313583"}], "description": null}, {"id": "3f533bb3-541c-4868-8883-69a5f1be7c80", "name": "builder-ppc64el-cpu16-ram16-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/3f533bb3-541c-4868-8883-69a5f1be7c80"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/3f533bb3-541c-4868-8883-69a5f1be7c80"}], "description": null}, {"id": "40ca84e0-d087-4f4b-bba2-e1823c6d3b85", "name": "builder-ppc64el-cpu8-ram8-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/40ca84e0-d087-4f4b-bba2-e1823c6d3b85"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/40ca84e0-d087-4f4b-bba2-e1823c6d3b85"}], "description": null}, {"id": "47276443-70e8-487f-9aaa-ef1a05b07c3c", "name": "builder-ppc64el-cpu4-ram105-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/47276443-70e8-487f-9aaa-ef1a05b07c3c"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/47276443-70e8-487f-9aaa-ef1a05b07c3c"}], "description": null}, {"id": "4d315fef-8774-4e68-916d-a6f08c302c0c", "name": "builder-ppc64el-cpu16-ram32-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/4d315fef-8774-4e68-916d-a6f08c302c0c"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/4d315fef-8774-4e68-916d-a6f08c302c0c"}], "description": null}, {"id": "4ea8e0b3-bd6c-4df2-a3bd-2b7dea6aea13", "name": "builder-ppc64el-cpu4-ram8-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/4ea8e0b3-bd6c-4df2-a3bd-2b7dea6aea13"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/4ea8e0b3-bd6c-4df2-a3bd-2b7dea6aea13"}], "description": null}, {"id": "503bfc0d-e770-441c-90b7-7049e4bdbe7e", "name": "builder-ppc64el-cpu8-ram120-disk28", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/503bfc0d-e770-441c-90b7-7049e4bdbe7e"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/503bfc0d-e770-441c-90b7-7049e4bdbe7e"}], "description": null}, {"id": "510412bb-aeb3-43d8-a0f0-cdb0cf97a5f2", "name": "builder-ppc64el-cpu4-ram4-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/510412bb-aeb3-43d8-a0f0-cdb0cf97a5f2"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/510412bb-aeb3-43d8-a0f0-cdb0cf97a5f2"}], "description": null}, {"id": "53b9821c-da67-415d-990c-2f023ff61d1e", "name": "builder-ppc64el-cpu8-ram32-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/53b9821c-da67-415d-990c-2f023ff61d1e"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/53b9821c-da67-415d-990c-2f023ff61d1e"}], "description": null}, {"id": "556a816f-2280-4167-bba4-0319a6d3aba9", "name": "builder-ppc64el-cpu8-ram4-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/556a816f-2280-4167-bba4-0319a6d3aba9"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/556a816f-2280-4167-bba4-0319a6d3aba9"}], "description": null}, {"id": "560c2269-9192-4b41-8787-506b25ef7067", "name": "builder-ppc64el-cpu8-ram8-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/560c2269-9192-4b41-8787-506b25ef7067"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/560c2269-9192-4b41-8787-506b25ef7067"}], "description": null}, {"id": "57403612-9552-4ada-8e55-b40624c3d8f4", "name": "builder-ppc64el-cpu8-ram16-disk500", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/57403612-9552-4ada-8e55-b40624c3d8f4"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/57403612-9552-4ada-8e55-b40624c3d8f4"}], "description": null}, {"id": "59bee3ae-a610-4f1a-b13f-a5f3400d2412", "name": "builder-ppc64el-cpu16-ram16-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/59bee3ae-a610-4f1a-b13f-a5f3400d2412"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/59bee3ae-a610-4f1a-b13f-a5f3400d2412"}], "description": null}, {"id": "5bf0bfb6-311e-4895-a22e-228b091cde43", "name": "builder-ppc64el-cpu24-ram64-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/5bf0bfb6-311e-4895-a22e-228b091cde43"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/5bf0bfb6-311e-4895-a22e-228b091cde43"}], "description": null}, {"id": "5d1a2077-5359-4a36-922a-351690cae9cc", "name": "builder-ppc64el-cpu4-ram8-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/5d1a2077-5359-4a36-922a-351690cae9cc"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/5d1a2077-5359-4a36-922a-351690cae9cc"}], "description": null}, {"id": "60cc1be7-1fa9-49e9-8702-419f39585f4b", "name": "builder-ppc64el-cpu8-ram16-disk200", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/60cc1be7-1fa9-49e9-8702-419f39585f4b"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/60cc1be7-1fa9-49e9-8702-419f39585f4b"}], "description": null}, {"id": "62f8dfc9-c388-44d0-962f-79bb9917cd11", "name": "builder-ppc64el-cpu2-ram44-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/62f8dfc9-c388-44d0-962f-79bb9917cd11"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/62f8dfc9-c388-44d0-962f-79bb9917cd11"}], "description": null}, {"id": "6679449d-f912-473e-82a2-42546b3087e2", "name": "builder-ppc64el-cpu24-ram128-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/6679449d-f912-473e-82a2-42546b3087e2"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/6679449d-f912-473e-82a2-42546b3087e2"}], "description": null}, {"id": "694472bd-b1d9-4708-a626-5e5b3dc7e09a", "name": "builder-ppc64el-cpu4-ram8-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/694472bd-b1d9-4708-a626-5e5b3dc7e09a"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/694472bd-b1d9-4708-a626-5e5b3dc7e09a"}], "description": null}, {"id": "696dde5e-582a-44cf-a030-ef883bc20144", "name": "builder-ppc64el-cpu8-ram16-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/696dde5e-582a-44cf-a030-ef883bc20144"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/696dde5e-582a-44cf-a030-ef883bc20144"}], "description": null}, {"id": "6e611cfc-91b1-4ade-877b-32b26ee297eb", "name": "builder-ppc64el-cpu2-ram16-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/6e611cfc-91b1-4ade-877b-32b26ee297eb"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/6e611cfc-91b1-4ade-877b-32b26ee297eb"}], "description": null}, {"id": "6e66fb56-0aa8-47f9-a877-e48efe207344", "name": "builder-ppc64el-cpu8-ram32-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/6e66fb56-0aa8-47f9-a877-e48efe207344"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/6e66fb56-0aa8-47f9-a877-e48efe207344"}], "description": null}, {"id": "70ba6763-188c-45d0-bb63-7e7930afb1aa", "name": "builder-ppc64el-cpu32-ram256-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/70ba6763-188c-45d0-bb63-7e7930afb1aa"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/70ba6763-188c-45d0-bb63-7e7930afb1aa"}], "description": null}, {"id": "73ce7235-e8b9-4370-aeba-3a33729c46b3", "name": "builder-ppc64el-cpu4-ram16-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/73ce7235-e8b9-4370-aeba-3a33729c46b3"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/73ce7235-e8b9-4370-aeba-3a33729c46b3"}], "description": null}, {"id": "74ef175b-e74b-4750-a5c3-abcefba98501", "name": "builder-ppc64el-cpu8-ram12-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/74ef175b-e74b-4750-a5c3-abcefba98501"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/74ef175b-e74b-4750-a5c3-abcefba98501"}], "description": null}, {"id": "79aee276-b044-40e3-bf50-9ba4009d1400", "name": "builder-ppc64el-cpu8-ram32-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/79aee276-b044-40e3-bf50-9ba4009d1400"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/79aee276-b044-40e3-bf50-9ba4009d1400"}], "description": null}, {"id": "79e5d123-cfc1-4b78-a85b-b607091140eb", "name": "builder-ppc64el-cpu64-ram128-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/79e5d123-cfc1-4b78-a85b-b607091140eb"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/79e5d123-cfc1-4b78-a85b-b607091140eb"}], "description": null}, {"id": "7c20dd8b-310a-4013-ac86-21fdfb5ff536", "name": "builder-ppc64el-cpu8-ram128-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/7c20dd8b-310a-4013-ac86-21fdfb5ff536"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/7c20dd8b-310a-4013-ac86-21fdfb5ff536"}], "description": null}, {"id": "82e7fa99-f07c-46de-8f52-b92ad80a561a", "name": "builder-ppc64el-cpu2-ram16-disk68", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/82e7fa99-f07c-46de-8f52-b92ad80a561a"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/82e7fa99-f07c-46de-8f52-b92ad80a561a"}], "description": null}, {"id": "85159e74-03c6-4178-bb31-e756efd11acb", "name": "builder-ppc64el-cpu16-ram8-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/85159e74-03c6-4178-bb31-e756efd11acb"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/85159e74-03c6-4178-bb31-e756efd11acb"}], "description": null}, {"id": "85f8b76d-5d7f-4f2a-998c-cd1d11c834ac", "name": "builder-ppc64el-cpu4-ram64-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/85f8b76d-5d7f-4f2a-998c-cd1d11c834ac"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/85f8b76d-5d7f-4f2a-998c-cd1d11c834ac"}], "description": null}, {"id": "861fa361-94af-45b2-9de2-5cbe0df87b1f", "name": "builder-ppc64el-cpu4-ram12-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/861fa361-94af-45b2-9de2-5cbe0df87b1f"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/861fa361-94af-45b2-9de2-5cbe0df87b1f"}], "description": null}, {"id": "88f7a27b-bd61-4d5e-a90f-391ef9d78fc4", "name": "builder-ppc64el-cpu4-ram105-disk28", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/88f7a27b-bd61-4d5e-a90f-391ef9d78fc4"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/88f7a27b-bd61-4d5e-a90f-391ef9d78fc4"}], "description": null}, {"id": "89afc706-8e2c-4ccd-b411-2d387d894209", "name": "builder-ppc64el-cpu2-ram16-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/89afc706-8e2c-4ccd-b411-2d387d894209"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/89afc706-8e2c-4ccd-b411-2d387d894209"}], "description": null}, {"id": "905418ec-52e8-4ae7-adf1-ccef895e14c2", "name": "builder-ppc64el-cpu4-ram64-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/905418ec-52e8-4ae7-adf1-ccef895e14c2"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/905418ec-52e8-4ae7-adf1-ccef895e14c2"}], "description": null}, {"id": "95b1a0b4-1ecc-4ceb-a8d6-2d3bdefbce79", "name": "builder-ppc64el-cpu2-ram8-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/95b1a0b4-1ecc-4ceb-a8d6-2d3bdefbce79"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/95b1a0b4-1ecc-4ceb-a8d6-2d3bdefbce79"}], "description": null}, {"id": "97704ac8-c97f-4f00-8e0d-85aa4e940154", "name": "builder-ppc64el-cpu2-ram12-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/97704ac8-c97f-4f00-8e0d-85aa4e940154"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/97704ac8-c97f-4f00-8e0d-85aa4e940154"}], "description": null}, {"id": "9a51418a-b43e-417c-9d1d-5c706d3ca620", "name": "builder-ppc64el-cpu8-ram40-disk68", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/9a51418a-b43e-417c-9d1d-5c706d3ca620"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/9a51418a-b43e-417c-9d1d-5c706d3ca620"}], "description": null}, {"id": "9af1f804-8d3b-4769-b317-63a8ee73942b", "name": "builder-ppc64el-cpu4-ram8-disk200", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/9af1f804-8d3b-4769-b317-63a8ee73942b"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/9af1f804-8d3b-4769-b317-63a8ee73942b"}], "description": null}, {"id": "9b15a7c7-c4c2-4841-b95e-928a217f2995", "name": "builder-ppc64el-cpu128-ram128-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/9b15a7c7-c4c2-4841-b95e-928a217f2995"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/9b15a7c7-c4c2-4841-b95e-928a217f2995"}], "description": null}, {"id": "9bec8a82-6767-45bd-826f-abd939beb5e3", "name": "builder-ppc64el-cpu4-ram12-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/9bec8a82-6767-45bd-826f-abd939beb5e3"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/9bec8a82-6767-45bd-826f-abd939beb5e3"}], "description": null}, {"id": "9e195c66-66cf-4314-bf0c-7b24de55e52f", "name": "builder-ppc64el-cpu8-ram64-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/9e195c66-66cf-4314-bf0c-7b24de55e52f"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/9e195c66-66cf-4314-bf0c-7b24de55e52f"}], "description": null}, {"id": "a37e29b1-11ac-4bd5-a015-a9ee46ed25b8", "name": "builder-ppc64el-cpu32-ram128-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/a37e29b1-11ac-4bd5-a015-a9ee46ed25b8"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/a37e29b1-11ac-4bd5-a015-a9ee46ed25b8"}], "description": null}, {"id": "a8157747-dcd3-4c19-98b7-df687076ae87", "name": "builder-ppc64el-cpu4-ram4-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/a8157747-dcd3-4c19-98b7-df687076ae87"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/a8157747-dcd3-4c19-98b7-df687076ae87"}], "description": null}, {"id": "a8d935bc-6ad6-4942-abdd-670d6421a03b", "name": "builder-ppc64el-cpu128-ram32-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/a8d935bc-6ad6-4942-abdd-670d6421a03b"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/a8d935bc-6ad6-4942-abdd-670d6421a03b"}], "description": null}, {"id": "ac354706-0335-4e10-a755-51a75b1a962c", "name": "builder-ppc64el-cpu4-ram8-disk120", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/ac354706-0335-4e10-a755-51a75b1a962c"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/ac354706-0335-4e10-a755-51a75b1a962c"}], "description": null}, {"id": "acb43878-9eee-4d8a-8ec0-610607dd1a28", "name": "builder-ppc64el-cpu128-ram64-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/acb43878-9eee-4d8a-8ec0-610607dd1a28"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/acb43878-9eee-4d8a-8ec0-610607dd1a28"}], "description": null}, {"id": "ad9b6a30-fa9a-400e-b49b-51f9a3c2eda9", "name": "builder-ppc64el-cpu4-ram72-disk28", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/ad9b6a30-fa9a-400e-b49b-51f9a3c2eda9"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/ad9b6a30-fa9a-400e-b49b-51f9a3c2eda9"}], "description": null}, {"id": "b1004655-b40b-44b4-be0b-7cf1763734a1", "name": "builder-ppc64el-cpu32-ram128-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/b1004655-b40b-44b4-be0b-7cf1763734a1"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/b1004655-b40b-44b4-be0b-7cf1763734a1"}], "description": null}, {"id": "b39a607b-bb86-4b68-a455-9dfcb714130f", "name": "builder-ppc64el-cpu4-ram72-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/b39a607b-bb86-4b68-a455-9dfcb714130f"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/b39a607b-bb86-4b68-a455-9dfcb714130f"}], "description": null}, {"id": "b5673781-1772-4bbf-8526-4d19486c6ac3", "name": "builder-ppc64el-cpu2-ram8-disk28", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/b5673781-1772-4bbf-8526-4d19486c6ac3"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/b5673781-1772-4bbf-8526-4d19486c6ac3"}], "description": null}, {"id": "b7538b06-d418-44a1-8ec5-30cc698ac005", "name": "builder-ppc64el-cpu16-ram32-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/b7538b06-d418-44a1-8ec5-30cc698ac005"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/b7538b06-d418-44a1-8ec5-30cc698ac005"}], "description": null}, {"id": "bc3d73f7-47c5-4533-9915-5da668c18032", "name": "builder-ppc64el-cpu4-ram4-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/bc3d73f7-47c5-4533-9915-5da668c18032"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/bc3d73f7-47c5-4533-9915-5da668c18032"}], "description": null}, {"id": "be11f608-8f5e-4e93-8b39-2e062fc23eb1", "name": "builder-ppc64el-cpu16-ram64-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/be11f608-8f5e-4e93-8b39-2e062fc23eb1"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/be11f608-8f5e-4e93-8b39-2e062fc23eb1"}], "description": null}, {"id": "c7e29ea5-b92f-4011-bc7c-1a81af4e8e98", "name": "builder-ppc64el-cpu8-ram16-disk1000", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/c7e29ea5-b92f-4011-bc7c-1a81af4e8e98"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/c7e29ea5-b92f-4011-bc7c-1a81af4e8e98"}], "description": null}, {"id": "ccda5e60-c156-4367-aeaf-25d9cd9fc4d8", "name": "builder-ppc64el-cpu4-ram24-disk68", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/ccda5e60-c156-4367-aeaf-25d9cd9fc4d8"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/ccda5e60-c156-4367-aeaf-25d9cd9fc4d8"}], "description": null}, {"id": "cdc72dd8-3a8d-4f6f-997b-60017a100228", "name": "builder-ppc64el-cpu4-ram40-disk188", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/cdc72dd8-3a8d-4f6f-997b-60017a100228"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/cdc72dd8-3a8d-4f6f-997b-60017a100228"}], "description": null}, {"id": "cedd22e7-22ba-425e-8ace-5a3607e63239", "name": "builder-ppc64el-cpu16-ram4-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/cedd22e7-22ba-425e-8ace-5a3607e63239"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/cedd22e7-22ba-425e-8ace-5a3607e63239"}], "description": null}, {"id": "cffc3023-932a-439e-8bb7-faf8f6d6c42a", "name": "builder-ppc64el-cpu16-ram128-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/cffc3023-932a-439e-8bb7-faf8f6d6c42a"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/cffc3023-932a-439e-8bb7-faf8f6d6c42a"}], "description": null}, {"id": "d0030e34-8145-4944-a92d-ba1e454c6126", "name": "builder-ppc64el-cpu64-ram256-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/d0030e34-8145-4944-a92d-ba1e454c6126"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/d0030e34-8145-4944-a92d-ba1e454c6126"}], "description": null}, {"id": "d24cccba-50db-4ebf-8e12-4f601202a489", "name": "builder-ppc64el-cpu2-ram4-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/d24cccba-50db-4ebf-8e12-4f601202a489"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/d24cccba-50db-4ebf-8e12-4f601202a489"}], "description": null}, {"id": "d3801d0d-ae1d-474a-be3f-c3b4e0d75ce6", "name": "builder-ppc64el-cpu4-ram32-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/d3801d0d-ae1d-474a-be3f-c3b4e0d75ce6"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/d3801d0d-ae1d-474a-be3f-c3b4e0d75ce6"}], "description": null}, {"id": "d4a9ba53-090a-4189-a822-48d3e2d80aa2", "name": "builder-ppc64el-cpu2-ram32-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/d4a9ba53-090a-4189-a822-48d3e2d80aa2"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/d4a9ba53-090a-4189-a822-48d3e2d80aa2"}], "description": null}, {"id": "d5142b95-4b59-484a-8d9d-e0519b9fdbba", "name": "builder-ppc64el-cpu4-ram32-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/d5142b95-4b59-484a-8d9d-e0519b9fdbba"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/d5142b95-4b59-484a-8d9d-e0519b9fdbba"}], "description": null}, {"id": "d67d41f2-0658-4e81-ac4f-abc5e19944a7", "name": "builder-ppc64el-cpu2-ram64-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/d67d41f2-0658-4e81-ac4f-abc5e19944a7"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/d67d41f2-0658-4e81-ac4f-abc5e19944a7"}], "description": null}, {"id": "d7441372-a91d-47c8-89a4-c08f59ece241", "name": "builder-ppc64el-cpu16-ram32-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/d7441372-a91d-47c8-89a4-c08f59ece241"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/d7441372-a91d-47c8-89a4-c08f59ece241"}], "description": null}, {"id": "da39261b-e816-43f1-a7bb-f5e784e73fbb", "name": "builder-ppc64el-cpu16-ram16-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/da39261b-e816-43f1-a7bb-f5e784e73fbb"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/da39261b-e816-43f1-a7bb-f5e784e73fbb"}], "description": null}, {"id": "dcc8e80f-6e4d-4f7d-a68f-298ebcb4376d", "name": "builder-ppc64el-cpu32-ram256-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/dcc8e80f-6e4d-4f7d-a68f-298ebcb4376d"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/dcc8e80f-6e4d-4f7d-a68f-298ebcb4376d"}], "description": null}, {"id": "dd1211e5-4133-400a-9dc9-71fa83fd4d97", "name": "builder-ppc64el-cpu2-ram55-disk28", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/dd1211e5-4133-400a-9dc9-71fa83fd4d97"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/dd1211e5-4133-400a-9dc9-71fa83fd4d97"}], "description": null}, {"id": "dfa7dc00-528e-45c5-b267-3d798e73e8da", "name": "builder-ppc64el-cpu8-ram4-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/dfa7dc00-528e-45c5-b267-3d798e73e8da"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/dfa7dc00-528e-45c5-b267-3d798e73e8da"}], "description": null}, {"id": "e2116c8a-a35a-432f-8bf7-06bef30c10ae", "name": "builder-ppc64el-cpu8-ram12-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/e2116c8a-a35a-432f-8bf7-06bef30c10ae"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/e2116c8a-a35a-432f-8bf7-06bef30c10ae"}], "description": null}, {"id": "e2818c96-49bf-4337-a614-ae546d7d7302", "name": "builder-ppc64el-cpu4-ram32-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/e2818c96-49bf-4337-a614-ae546d7d7302"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/e2818c96-49bf-4337-a614-ae546d7d7302"}], "description": null}, {"id": "e628d527-f077-426d-9380-5eea778aabc2", "name": "builder-ppc64el-cpu8-ram16-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/e628d527-f077-426d-9380-5eea778aabc2"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/e628d527-f077-426d-9380-5eea778aabc2"}], "description": null}, {"id": "e752e039-cbe4-4a16-8197-de87ba42b83e", "name": "builder-ppc64el-cpu64-ram256-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/e752e039-cbe4-4a16-8197-de87ba42b83e"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/e752e039-cbe4-4a16-8197-de87ba42b83e"}], "description": null}, {"id": "e7f811c8-a60c-45c6-86c8-8e4b025751df", "name": "builder-ppc64el-cpu4-ram16-disk40", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/e7f811c8-a60c-45c6-86c8-8e4b025751df"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/e7f811c8-a60c-45c6-86c8-8e4b025751df"}], "description": null}, {"id": "eb80d7e2-b6e1-42a5-b80d-3dad861f6989", "name": "builder-ppc64el-cpu16-ram4-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/eb80d7e2-b6e1-42a5-b80d-3dad861f6989"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/eb80d7e2-b6e1-42a5-b80d-3dad861f6989"}], "description": null}, {"id": "ed127e2b-02b8-4e61-bf10-0c89b90928e6", "name": "builder-ppc64el-cpu64-ram128-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/ed127e2b-02b8-4e61-bf10-0c89b90928e6"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/ed127e2b-02b8-4e61-bf10-0c89b90928e6"}], "description": null}, {"id": "ef7301a7-71f4-48ac-b387-23251f4060e1", "name": "builder-ppc64el-cpu16-ram8-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/ef7301a7-71f4-48ac-b387-23251f4060e1"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/ef7301a7-71f4-48ac-b387-23251f4060e1"}], "description": null}, {"id": "f0f1af4d-f230-40c1-b789-c94e02a68daa", "name": "builder-ppc64el-cpu16-ram8-disk20", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/f0f1af4d-f230-40c1-b789-c94e02a68daa"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/f0f1af4d-f230-40c1-b789-c94e02a68daa"}], "description": null}, {"id": "f40b2dbc-5d69-40b0-a9fc-71c32de93ca3", "name": "autopkgtest-big-ppc64el", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/f40b2dbc-5d69-40b0-a9fc-71c32de93ca3"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/f40b2dbc-5d69-40b0-a9fc-71c32de93ca3"}], "description": null}, {"id": "f6aae414-e26b-4692-95d4-d851b6993c2a", "name": "builder-ppc64el-cpu2-ram8-disk50", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/f6aae414-e26b-4692-95d4-d851b6993c2a"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/f6aae414-e26b-4692-95d4-d851b6993c2a"}], "description": null}, {"id": "f91b245b-ad92-47f6-8861-d1e070fcc19c", "name": "builder-ppc64el-cpu2-ram64-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/f91b245b-ad92-47f6-8861-d1e070fcc19c"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/f91b245b-ad92-47f6-8861-d1e070fcc19c"}], "description": null}, {"id": "fa3bbba4-5e72-4ca3-9661-ccf45947bbf5", "name": "builder-ppc64el-cpu16-ram4-disk100", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/fa3bbba4-5e72-4ca3-9661-ccf45947bbf5"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/fa3bbba4-5e72-4ca3-9661-ccf45947bbf5"}], "description": null}, {"id": "ff4cf1ee-6e00-49b7-9d11-fafa69b910df", "name": "builder-ppc64el-cpu8-ram32-disk40", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/ff4cf1ee-6e00-49b7-9d11-fafa69b910df"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/ff4cf1ee-6e00-49b7-9d11-fafa69b910df"}], "description": null}]} 424s DEBUG (session:936) GET call to compute for https://nova.ps6.canonical.com:8774/v2.1/flavors?is_public=None used request id req-b5b97936-a63f-4f85-92ec-5d7885cc1f50 424s DEBUG (session:517) REQ: curl -g -i -X GET https://nova.ps6.canonical.com:8774/v2.1/flavors/102d0b57-e8d2-46c6-9be4-f452119a0280 -H "Accept: application/json" -H "OpenStack-API-Version: compute 2.87" -H "User-Agent: python-novaclient" -H "X-Auth-Token: {SHA256}bd8ed50138f633602170b409961fbe057d2ef70333a865d83dbeb4f375266907" -H "X-OpenStack-Nova-API-Version: 2.87" 424s DEBUG (connectionpool:429) https://nova.ps6.canonical.com:8774 "GET /v2.1/flavors/102d0b57-e8d2-46c6-9be4-f452119a0280 HTTP/1.1" 200 623 424s DEBUG (session:548) RESP: [200] Connection: Keep-Alive Content-Length: 623 Content-Type: application/json Date: Mon, 06 Jan 2025 11:38:51 GMT Keep-Alive: timeout=75, max=996 OpenStack-API-Version: compute 2.87 Server: Apache/2.4.52 (Ubuntu) Vary: OpenStack-API-Version,X-OpenStack-Nova-API-Version X-OpenStack-Nova-API-Version: 2.87 x-compute-request-id: req-e471c609-943e-42de-b2ae-63e847edd4cd x-openstack-request-id: req-e471c609-943e-42de-b2ae-63e847edd4cd 424s DEBUG (session:580) RESP BODY: {"flavor": {"id": "102d0b57-e8d2-46c6-9be4-f452119a0280", "name": "autopkgtest-ppc64el", "ram": 4096, "disk": 20, "swap": 0, "OS-FLV-EXT-DATA:ephemeral": 0, "OS-FLV-DISABLED:disabled": false, "vcpus": 2, "os-flavor-access:is_public": false, "rxtx_factor": 1.0, "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/flavors/102d0b57-e8d2-46c6-9be4-f452119a0280"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/flavors/102d0b57-e8d2-46c6-9be4-f452119a0280"}], "description": null, "extra_specs": {"aggregate_instance_extra_specs:commit": "builder-ppc64el", "hw_rng:allowed": "True"}}} 424s DEBUG (session:936) GET call to compute for https://nova.ps6.canonical.com:8774/v2.1/flavors/102d0b57-e8d2-46c6-9be4-f452119a0280 used request id req-e471c609-943e-42de-b2ae-63e847edd4cd 424s DEBUG (session:517) REQ: curl -g -i -X POST https://nova.ps6.canonical.com:8774/v2.1/servers -H "Accept: application/json" -H "Content-Type: application/json" -H "OpenStack-API-Version: compute 2.87" -H "User-Agent: python-novaclient" -H "X-Auth-Token: {SHA256}bd8ed50138f633602170b409961fbe057d2ef70333a865d83dbeb4f375266907" -H "X-OpenStack-Nova-API-Version: 2.87" -d '{"server": {"name": "adt-plucky-ppc64el-slony1-2-20250106-113738-juju-7f2275-prod-proposed-migration-environment-20-c781bbe5-9201-4e22-b3fd-a94884e1d410", "imageRef": "66818982-bc25-4f66-80f3-4b4ddeb5bc55", "flavorRef": "102d0b57-e8d2-46c6-9be4-f452119a0280", "user_data": "I2Nsb3VkLWNvbmZpZwpob3N0bmFtZTogYXV0b3BrZ3Rlc3QKZnFkbjogYXV0b3BrZ3Rlc3QubG9jYWwKbWFuYWdlX2V0Y19ob3N0czogdHJ1ZQphcHRfdXBkYXRlOiB0cnVlCmFwdF91cGdyYWRlOiBmYWxzZQphcHRfbWlycm9yOiBodHRwOi8vZnRwbWFzdGVyLmludGVybmFsL3VidW50dS8KCnJ1bmNtZDoKIC0gZWNobyAnQWNxdWlyZTo6TGFuZ3VhZ2VzICJub25lIjsnID4gL2V0Yy9hcHQvYXB0LmNvbmYuZC85MG5vbGFuZ3VhZ2VzCiAtIGVjaG8gJ2ZvcmNlLXVuc2FmZS1pbycgPiAvZXRjL2Rwa2cvZHBrZy5jZmcuZC9hdXRvcGtndGVzdAogLSBwcmludGYgJ1xuVEVSTT1saW51eFxuJ2h0dHBfcHJveHk9aHR0cDovL3NxdWlkLmludGVybmFsOjMxMjgnXG4naHR0cHNfcHJveHk9aHR0cDovL3NxdWlkLmludGVybmFsOjMxMjgnXG4nbm9fcHJveHk9MTI3LjAuMC4xLDEyNy4wLjEuMSxsb2dpbi51YnVudHUuY29tLGxvY2FsaG9zdCxsb2NhbGRvbWFpbixub3ZhbG9jYWwsaW50ZXJuYWwsYXJjaGl2ZS51YnVudHUuY29tLHBvcnRzLnVidW50dS5jb20sc2VjdXJpdHkudWJ1bnR1LmNvbSxkZGVicy51YnVudHUuY29tLGNoYW5nZWxvZ3MudWJ1bnR1LmNvbSxrZXlzZXJ2ZXIudWJ1bnR1LmNvbSxsYXVuY2hwYWRsaWJyYXJpYW4ubmV0LGxhdW5jaHBhZGNvbnRlbnQubmV0LGxhdW5jaHBhZC5uZXQsMTAuMjQuMC4wLzI0LGtleXN0b25lLnBzNS5jYW5vbmljYWwuY29tLG9iamVjdHN0b3JhZ2UucHJvZHN0YWNrNS5jYW5vbmljYWwuY29tLHJhZG9zZ3cucHM1LmNhbm9uaWNhbC5jb20nXG4nID4+IC9ldGMvZW52aXJvbm1lbnQKIC0gc2VkIC1pIC1yICcvXjEyNy4wLjEuMS8gcy9hdXRvcGtndGVzdC1bXiBdK1wuL2F1dG9wa2d0ZXN0XC4vJyAvZXRjL2hvc3RzCg==", "key_name": "testbed-juju-7f2275-prod-proposed-migration-environment-20", "min_count": 1, "max_count": 1, "security_groups": [{"name": "autopkgtest-juju-7f2275-prod-proposed-migration-environment-20@bos03-ppc64el-7.secgroup"}], "networks": [{"uuid": "3083d638-5564-4f5c-97ef-09f045123d20"}]}}' 424s DEBUG (connectionpool:429) https://nova.ps6.canonical.com:8774 "POST /v2.1/servers HTTP/1.1" 202 478 424s DEBUG (session:548) RESP: [202] Connection: Keep-Alive Content-Length: 478 Content-Type: application/json Date: Mon, 06 Jan 2025 11:38:52 GMT Keep-Alive: timeout=75, max=995 OpenStack-API-Version: compute 2.87 Server: Apache/2.4.52 (Ubuntu) Vary: OpenStack-API-Version,X-OpenStack-Nova-API-Version X-OpenStack-Nova-API-Version: 2.87 location: https://nova.ps6.canonical.com:8774/v2.1/servers/7d8dc449-fe71-414f-a7d4-1496512e0071 x-compute-request-id: req-d6db41a7-0cf6-4e56-a96c-e411f0f608cf x-openstack-request-id: req-d6db41a7-0cf6-4e56-a96c-e411f0f608cf 424s DEBUG (session:580) RESP BODY: {"server": {"id": "7d8dc449-fe71-414f-a7d4-1496512e0071", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/servers/7d8dc449-fe71-414f-a7d4-1496512e0071"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/servers/7d8dc449-fe71-414f-a7d4-1496512e0071"}], "OS-DCF:diskConfig": "MANUAL", "security_groups": [{"name": "autopkgtest-juju-7f2275-prod-proposed-migration-environment-20@bos03-ppc64el-7.secgroup"}], "adminPass": "cn5QUc24RrYB"}} 424s DEBUG (session:936) POST call to compute for https://nova.ps6.canonical.com:8774/v2.1/servers used request id req-d6db41a7-0cf6-4e56-a96c-e411f0f608cf 424s DEBUG (session:517) REQ: curl -g -i -X GET https://nova.ps6.canonical.com:8774/v2.1/servers/7d8dc449-fe71-414f-a7d4-1496512e0071 -H "Accept: application/json" -H "OpenStack-API-Version: compute 2.87" -H "User-Agent: python-novaclient" -H "X-Auth-Token: {SHA256}bd8ed50138f633602170b409961fbe057d2ef70333a865d83dbeb4f375266907" -H "X-OpenStack-Nova-API-Version: 2.87" 424s DEBUG (connectionpool:429) https://nova.ps6.canonical.com:8774 "GET /v2.1/servers/7d8dc449-fe71-414f-a7d4-1496512e0071 HTTP/1.1" 200 3236 424s DEBUG (session:548) RESP: [200] Connection: Keep-Alive Content-Length: 3236 Content-Type: application/json Date: Mon, 06 Jan 2025 11:38:52 GMT Keep-Alive: timeout=75, max=994 OpenStack-API-Version: compute 2.87 Server: Apache/2.4.52 (Ubuntu) Vary: OpenStack-API-Version,X-OpenStack-Nova-API-Version X-OpenStack-Nova-API-Version: 2.87 x-compute-request-id: req-236cad91-6f2c-4c8d-a5d8-79ade0a66ee6 x-openstack-request-id: req-236cad91-6f2c-4c8d-a5d8-79ade0a66ee6 424s DEBUG (session:580) RESP BODY: {"server": {"id": "7d8dc449-fe71-414f-a7d4-1496512e0071", "name": "adt-plucky-ppc64el-slony1-2-20250106-113738-juju-7f2275-prod-proposed-migration-environment-20-c781bbe5-9201-4e22-b3fd-a94884e1d410", "status": "BUILD", "tenant_id": "623df63b80274c21bc79a0c35e68d615", "user_id": "c871debdeffd4cb8b69ce618fc4aa361", "metadata": {}, "hostId": "", "image": {"id": "66818982-bc25-4f66-80f3-4b4ddeb5bc55", "links": [{"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/images/66818982-bc25-4f66-80f3-4b4ddeb5bc55"}]}, "flavor": {"vcpus": 2, "ram": 4096, "disk": 20, "ephemeral": 0, "swap": 0, "original_name": "autopkgtest-ppc64el", "extra_specs": {"aggregate_instance_extra_specs:commit": "builder-ppc64el", "hw_rng:allowed": "True"}}, "created": "2025-01-06T11:38:53Z", "updated": "2025-01-06T11:38:52Z", "addresses": {}, "accessIPv4": "", "accessIPv6": "", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/servers/7d8dc449-fe71-414f-a7d4-1496512e0071"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/servers/7d8dc449-fe71-414f-a7d4-1496512e0071"}], "OS-DCF:diskConfig": "MANUAL", "progress": 0, "OS-EXT-AZ:availability_zone": "", "config_drive": "", "key_name": "testbed-juju-7f2275-prod-proposed-migration-environment-20", "OS-SRV-USG:launched_at": null, "OS-SRV-USG:terminated_at": null, "OS-EXT-SRV-ATTR:host": null, "OS-EXT-SRV-ATTR:instance_name": "", "OS-EXT-SRV-ATTR:hypervisor_hostname": null, "OS-EXT-SRV-ATTR:reservation_id": "r-dcabekwk", "OS-EXT-SRV-ATTR:launch_index": 0, "OS-EXT-SRV-ATTR:hostname": "adt-plucky-ppc64el-slony1-2-20250106-113738-juju-7f2275-prod-pr", "OS-EXT-SRV-ATTR:kernel_id": "", "OS-EXT-SRV-ATTR:ramdisk_id": "", "OS-EXT-SRV-ATTR:root_device_name": null, "OS-EXT-SRV-ATTR:user_data": "I2Nsb3VkLWNvbmZpZwpob3N0bmFtZTogYXV0b3BrZ3Rlc3QKZnFkbjogYXV0b3BrZ3Rlc3QubG9jYWwKbWFuYWdlX2V0Y19ob3N0czogdHJ1ZQphcHRfdXBkYXRlOiB0cnVlCmFwdF91cGdyYWRlOiBmYWxzZQphcHRfbWlycm9yOiBodHRwOi8vZnRwbWFzdGVyLmludGVybmFsL3VidW50dS8KCnJ1bmNtZDoKIC0gZWNobyAnQWNxdWlyZTo6TGFuZ3VhZ2VzICJub25lIjsnID4gL2V0Yy9hcHQvYXB0LmNvbmYuZC85MG5vbGFuZ3VhZ2VzCiAtIGVjaG8gJ2ZvcmNlLXVuc2FmZS1pbycgPiAvZXRjL2Rwa2cvZHBrZy5jZmcuZC9hdXRvcGtndGVzdAogLSBwcmludGYgJ1xuVEVSTT1saW51eFxuJ2h0dHBfcHJveHk9aHR0cDovL3NxdWlkLmludGVybmFsOjMxMjgnXG4naHR0cHNfcHJveHk9aHR0cDovL3NxdWlkLmludGVybmFsOjMxMjgnXG4nbm9fcHJveHk9MTI3LjAuMC4xLDEyNy4wLjEuMSxsb2dpbi51YnVudHUuY29tLGxvY2FsaG9zdCxsb2NhbGRvbWFpbixub3ZhbG9jYWwsaW50ZXJuYWwsYXJjaGl2ZS51YnVudHUuY29tLHBvcnRzLnVidW50dS5jb20sc2VjdXJpdHkudWJ1bnR1LmNvbSxkZGVicy51YnVudHUuY29tLGNoYW5nZWxvZ3MudWJ1bnR1LmNvbSxrZXlzZXJ2ZXIudWJ1bnR1LmNvbSxsYXVuY2hwYWRsaWJyYXJpYW4ubmV0LGxhdW5jaHBhZGNvbnRlbnQubmV0LGxhdW5jaHBhZC5uZXQsMTAuMjQuMC4wLzI0LGtleXN0b25lLnBzNS5jYW5vbmljYWwuY29tLG9iamVjdHN0b3JhZ2UucHJvZHN0YWNrNS5jYW5vbmljYWwuY29tLHJhZG9zZ3cucHM1LmNhbm9uaWNhbC5jb20nXG4nID4+IC9ldGMvZW52aXJvbm1lbnQKIC0gc2VkIC1pIC1yICcvXjEyNy4wLjEuMS8gcy9hdXRvcGtndGVzdC1bXiBdK1wuL2F1dG9wa2d0ZXN0XC4vJyAvZXRjL2hvc3RzCg==", "OS-EXT-STS:task_state": "scheduling", "OS-EXT-STS:vm_state": "building", "OS-EXT-STS:power_state": 0, "os-extended-volumes:volumes_attached": [], "locked": false, "locked_reason": null, "description": null, "tags": [], "trusted_image_certificates": null, "server_groups": []}} 424s DEBUG (session:936) GET call to compute for https://nova.ps6.canonical.com:8774/v2.1/servers/7d8dc449-fe71-414f-a7d4-1496512e0071 used request id req-236cad91-6f2c-4c8d-a5d8-79ade0a66ee6 424s DEBUG (session:517) REQ: curl -g -i -X GET https://glance.ps6.canonical.com:9292/v2/images/66818982-bc25-4f66-80f3-4b4ddeb5bc55 -H "Accept: application/json" -H "OpenStack-API-Version: compute 2.87" -H "User-Agent: python-novaclient" -H "X-Auth-Token: {SHA256}bd8ed50138f633602170b409961fbe057d2ef70333a865d83dbeb4f375266907" -H "X-OpenStack-Nova-API-Version: 2.87" 424s DEBUG (connectionpool:429) https://glance.ps6.canonical.com:9292 "GET /v2/images/66818982-bc25-4f66-80f3-4b4ddeb5bc55 HTTP/1.1" 200 2294 424s DEBUG (session:548) RESP: [200] Connection: Keep-Alive Content-Length: 2294 Content-Type: application/json Date: Mon, 06 Jan 2025 11:38:52 GMT Keep-Alive: timeout=75, max=999 Server: Apache/2.4.52 (Ubuntu) X-Openstack-Request-Id: req-c9f8a301-0337-4ce6-9035-3a27f513b03f 424s DEBUG (session:580) RESP BODY: {"architecture": "ppc64le", "base_image_ref": "93404c41-3be3-4a13-b02b-2a1e42399530", "boot_roles": "member,load-balancer_member,reader", "content_id": "auto.sync", "hw_cdrom_bus": "scsi", "hw_disk_bus": "virtio", "hw_machine_type": "pseries", "hw_video_model": "vga", "hw_vif_model": "virtio", "image_location": "snapshot", "image_state": "available", "image_type": "snapshot", "instance_uuid": "aad2dc82-443a-4c50-8705-11e717de8820", "item_name": "disk1.img", "os_distro": "ubuntu", "os_version": "25.04", "owner_id": "623df63b80274c21bc79a0c35e68d615", "owner_project_name": "prod-proposed-migration-ppc64el_project", "owner_user_name": "prod-proposed-migration-ppc64el", "product_name": "com.ubuntu.cloud.daily:server:25.04:ppc64el", "simplestreams_metadata": "{\"aliases\": \"25.04,p,plucky,devel\", \"arch\": \"ppc64el\", \"ftype\": \"disk1.img\", \"label\": \"daily\", \"md5\": \"ba08164f86d9d01e6f74c296e51f14d5\", \"os\": \"ubuntu\", \"pubname\": \"ubuntu-plucky-daily-ppc64el-server-20241215\", \"release\": \"plucky\", \"release_codename\": \"P", "source_content_id": "com.ubuntu.cloud:daily:download", "user_id": "c871debdeffd4cb8b69ce618fc4aa361", "version_name": "20241215", "name": "adt/ubuntu-plucky-ppc64el-server-20250106.img", "disk_format": "qcow2", "container_format": "bare", "visibility": "private", "size": 2718105600, "virtual_size": 21474836480, "status": "active", "checksum": "242e65660b61000980b64fef466c760c", "protected": false, "min_ram": 0, "min_disk": 20, "owner": "623df63b80274c21bc79a0c35e68d615", "os_hidden": false, "os_hash_algo": "sha512", "os_hash_value": "9e613a3d3079e982fbc0fee10f1f39f79fe37d8b1bdb338aca18f78f940868942bf6e68500bbd7a319d5eb547e9ce89f2a17755dc4d6bbc6a08fb821d76ac5a2", "id": "66818982-bc25-4f66-80f3-4b4ddeb5bc55", "created_at": "2025-01-06T02:14:41Z", "updated_at": "2025-01-06T02:15:10Z", "locations": [{"url": "rbd://eea9d068-c18c-11ed-8dc0-013aacb71b80/glance/66818982-bc25-4f66-80f3-4b4ddeb5bc55/snap", "metadata": {"store": "ceph"}}], "direct_url": "rbd://eea9d068-c18c-11ed-8dc0-013aacb71b80/glance/66818982-bc25-4f66-80f3-4b4ddeb5bc55/snap", "tags": [], "self": "/v2/images/66818982-bc25-4f66-80f3-4b4ddeb5bc55", "file": "/v2/images/66818982-bc25-4f66-80f3-4b4ddeb5bc55/file", "schema": "/v2/schemas/image", "stores": "ceph"} 424s DEBUG (session:936) GET call to image for https://glance.ps6.canonical.com:9292/v2/images/66818982-bc25-4f66-80f3-4b4ddeb5bc55 used request id req-c9f8a301-0337-4ce6-9035-3a27f513b03f 424s +--------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ 424s | Property | Value | 424s +--------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+ 424s | OS-DCF:diskConfig | MANUAL | 424s | OS-EXT-AZ:availability_zone | | 424s | OS-EXT-SRV-ATTR:host | - | 424s | OS-EXT-SRV-ATTR:hostname | adt-plucky-ppc64el-slony1-2-20250106-113738-juju-7f2275-prod-pr | 424s | OS-EXT-SRV-ATTR:hypervisor_hostname | - | 424s | OS-EXT-SRV-ATTR:instance_name | | 424s | OS-EXT-SRV-ATTR:kernel_id | | 424s | OS-EXT-SRV-ATTR:launch_index | 0 | 424s | OS-EXT-SRV-ATTR:ramdisk_id | | 424s | OS-EXT-SRV-ATTR:reservation_id | r-dcabekwk | 424s | OS-EXT-SRV-ATTR:root_device_name | - | 424s | OS-EXT-STS:power_state | 0 | 424s | OS-EXT-STS:task_state | scheduling | 424s | OS-EXT-STS:vm_state | building | 424s | OS-SRV-USG:launched_at | - | 424s | OS-SRV-USG:terminated_at | - | 424s | accessIPv4 | | 424s | accessIPv6 | | 424s | adminPass | cn5QUc24RrYB | 424s | config_drive | | 424s | created | 2025-01-06T11:38:53Z | 424s | description | - | 424s | flavor:disk | 20 | 424s | flavor:ephemeral | 0 | 424s | flavor:extra_specs | {"aggregate_instance_extra_specs:commit": "builder-ppc64el", "hw_rng:allowed": "True"} | 424s | flavor:original_name | autopkgtest-ppc64el | 424s | flavor:ram | 4096 | 424s | flavor:swap | 0 | 424s | flavor:vcpus | 2 | 424s | hostId | | 424s | id | 7d8dc449-fe71-414f-a7d4-1496512e0071 | 424s | image | adt/ubuntu-plucky-ppc64el-server-20250106.img (66818982-bc25-4f66-80f3-4b4ddeb5bc55) | 424s | key_name | testbed-juju-7f2275-prod-proposed-migration-environment-20 | 424s | locked | False | 424s | locked_reason | - | 424s | metadata | {} | 424s | name | adt-plucky-ppc64el-slony1-2-20250106-113738-juju-7f2275-prod-proposed-migration-environment-20-c781bbe5-9201-4e22-b3fd-a94884e1d410 | 424s | os-extended-volumes:volumes_attached | [] | 424s | progress | 0 | 424s | security_groups | autopkgtest-juju-7f2275-prod-proposed-migration-environment-20@bos03-ppc64el-7.secgroup | 424s | server_groups | [] | 424s | status | BUILD | 424s | tags | [] | 424s | tenant_id | 623df63b80274c21bc79a0c35e68d615 | 424s | trusted_image_certificates | - | 424s | updated | 2025-01-06T11:38:52Z | 424s | user_id | c871debdeffd4cb8b69ce618fc4aa361 | 424s +--------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------+DEBUG (session:517) REQ: curl -g -i -X GET https://nova.ps6.canonical.com:8774/v2.1/servers/7d8dc449-fe71-414f-a7d4-1496512e0071 -H "Accept: application/json" -H "OpenStack-API-Version: compute 2.87" -H "User-Agent: python-novaclient" -H "X-Auth-Token: {SHA256}bd8ed50138f633602170b409961fbe057d2ef70333a865d83dbeb4f375266907" -H "X-OpenStack-Nova-API-Version: 2.87" 424s DEBUG (connectionpool:429) https://nova.ps6.canonical.com:8774 "GET /v2.1/servers/7d8dc449-fe71-414f-a7d4-1496512e0071 HTTP/1.1" 200 3363 424s DEBUG (session:548) RESP: [200] Connection: Keep-Alive Content-Length: 3363 Content-Type: application/json Date: Mon, 06 Jan 2025 11:38:52 GMT Keep-Alive: timeout=75, max=993 OpenStack-API-Version: compute 2.87 Server: Apache/2.4.52 (Ubuntu) Vary: OpenStack-API-Version,X-OpenStack-Nova-API-Version X-OpenStack-Nova-API-Version: 2.87 x-compute-request-id: req-12beed8d-d177-45df-b471-f270fca8cc1a x-openstack-request-id: req-12beed8d-d177-45df-b471-f270fca8cc1a 424s DEBUG (session:580) RESP BODY: {"server": {"id": "7d8dc449-fe71-414f-a7d4-1496512e0071", "name": "adt-plucky-ppc64el-slony1-2-20250106-113738-juju-7f2275-prod-proposed-migration-environment-20-c781bbe5-9201-4e22-b3fd-a94884e1d410", "status": "ERROR", "tenant_id": "623df63b80274c21bc79a0c35e68d615", "user_id": "c871debdeffd4cb8b69ce618fc4aa361", "metadata": {}, "hostId": "", "image": {"id": "66818982-bc25-4f66-80f3-4b4ddeb5bc55", "links": [{"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/images/66818982-bc25-4f66-80f3-4b4ddeb5bc55"}]}, "flavor": {"vcpus": 2, "ram": 4096, "disk": 20, "ephemeral": 0, "swap": 0, "original_name": "autopkgtest-ppc64el", "extra_specs": {"aggregate_instance_extra_specs:commit": "builder-ppc64el", "hw_rng:allowed": "True"}}, "created": "2025-01-06T11:38:52Z", "updated": "2025-01-06T11:38:53Z", "addresses": {}, "accessIPv4": "", "accessIPv6": "", "links": [{"rel": "self", "href": "https://nova.ps6.canonical.com:8774/v2.1/servers/7d8dc449-fe71-414f-a7d4-1496512e0071"}, {"rel": "bookmark", "href": "https://nova.ps6.canonical.com:8774/servers/7d8dc449-fe71-414f-a7d4-1496512e0071"}], "OS-DCF:diskConfig": "MANUAL", "fault": {"code": 500, "created": "2025-01-06T11:38:53Z", "message": "No valid host was found. There are not enough hosts available."}, "OS-EXT-AZ:availability_zone": "", "config_drive": "", "key_name": "testbed-juju-7f2275-prod-proposed-migration-environment-20", "OS-SRV-USG:launched_at": null, "OS-SRV-USG:terminated_at": null, "OS-EXT-SRV-ATTR:host": null, "OS-EXT-SRV-ATTR:instance_name": "instance-0008fd9c", "OS-EXT-SRV-ATTR:hypervisor_hostname": null, "OS-EXT-SRV-ATTR:reservation_id": "r-dcabekwk", "OS-EXT-SRV-ATTR:launch_index": 0, "OS-EXT-SRV-ATTR:hostname": "adt-plucky-ppc64el-slony1-2-20250106-113738-juju-7f2275-prod-pr", "OS-EXT-SRV-ATTR:kernel_id": "", "OS-EXT-SRV-ATTR:ramdisk_id": "", "OS-EXT-SRV-ATTR:root_device_name": null, "OS-EXT-SRV-ATTR:user_data": "I2Nsb3VkLWNvbmZpZwpob3N0bmFtZTogYXV0b3BrZ3Rlc3QKZnFkbjogYXV0b3BrZ3Rlc3QubG9jYWwKbWFuYWdlX2V0Y19ob3N0czogdHJ1ZQphcHRfdXBkYXRlOiB0cnVlCmFwdF91cGdyYWRlOiBmYWxzZQphcHRfbWlycm9yOiBodHRwOi8vZnRwbWFzdGVyLmludGVybmFsL3VidW50dS8KCnJ1bmNtZDoKIC0gZWNobyAnQWNxdWlyZTo6TGFuZ3VhZ2VzICJub25lIjsnID4gL2V0Yy9hcHQvYXB0LmNvbmYuZC85MG5vbGFuZ3VhZ2VzCiAtIGVjaG8gJ2ZvcmNlLXVuc2FmZS1pbycgPiAvZXRjL2Rwa2cvZHBrZy5jZmcuZC9hdXRvcGtndGVzdAogLSBwcmludGYgJ1xuVEVSTT1saW51eFxuJ2h0dHBfcHJveHk9aHR0cDovL3NxdWlkLmludGVybmFsOjMxMjgnXG4naHR0cHNfcHJveHk9aHR0cDovL3NxdWlkLmludGVybmFsOjMxMjgnXG4nbm9fcHJveHk9MTI3LjAuMC4xLDEyNy4wLjEuMSxsb2dpbi51YnVudHUuY29tLGxvY2FsaG9zdCxsb2NhbGRvbWFpbixub3ZhbG9jYWwsaW50ZXJuYWwsYXJjaGl2ZS51YnVudHUuY29tLHBvcnRzLnVidW50dS5jb20sc2VjdXJpdHkudWJ1bnR1LmNvbSxkZGVicy51YnVudHUuY29tLGNoYW5nZWxvZ3MudWJ1bnR1LmNvbSxrZXlzZXJ2ZXIudWJ1bnR1LmNvbSxsYXVuY2hwYWRsaWJyYXJpYW4ubmV0LGxhdW5jaHBhZGNvbnRlbnQubmV0LGxhdW5jaHBhZC5uZXQsMTAuMjQuMC4wLzI0LGtleXN0b25lLnBzNS5jYW5vbmljYWwuY29tLG9iamVjdHN0b3JhZ2UucHJvZHN0YWNrNS5jYW5vbmljYWwuY29tLHJhZG9zZ3cucHM1LmNhbm9uaWNhbC5jb20nXG4nID4+IC9ldGMvZW52aXJvbm1lbnQKIC0gc2VkIC1pIC1yICcvXjEyNy4wLjEuMS8gcy9hdXRvcGtndGVzdC1bXiBdK1wuL2F1dG9wa2d0ZXN0XC4vJyAvZXRjL2hvc3RzCg==", "OS-EXT-STS:task_state": null, "OS-EXT-STS:vm_state": "error", "OS-EXT-STS:power_state": 0, "os-extended-volumes:volumes_attached": [], "locked": false, "locked_reason": null, "description": null, "tags": [], "trusted_image_certificates": null, "server_groups": []}} 424s DEBUG (session:936) GET call to compute for https://nova.ps6.canonical.com:8774/v2.1/servers/7d8dc449-fe71-414f-a7d4-1496512e0071 used request id req-12beed8d-d177-45df-b471-f270fca8cc1a 424s DEBUG (shell:822) 424s Traceback (most recent call last): 424s File "/usr/lib/python3/dist-packages/novaclient/shell.py", line 820, in main 424s OpenStackComputeShell().main(argv) 424s File "/usr/lib/python3/dist-packages/novaclient/shell.py", line 742, in main 424s args.func(self.cs, args) 424s File "/usr/lib/python3/dist-packages/novaclient/v2/shell.py", line 980, in do_boot 424s _poll_for_status(cs.servers.get, server.id, 'building', ['active']) 424s File "/usr/lib/python3/dist-packages/novaclient/v2/shell.py", line 1019, in _poll_for_status 424s raise exceptions.ResourceInErrorState(obj) 424s novaclient.exceptions.ResourceInErrorState: 424s ERROR (ResourceInErrorState): 424s 424s 424s 424s Error building server 426s autopkgtest [11:44:45]: testbed dpkg architecture: ppc64el 427s autopkgtest [11:44:46]: testbed apt version: 2.9.18 427s autopkgtest [11:44:46]: @@@@@@@@@@@@@@@@@@@@ test bed setup 427s autopkgtest [11:44:46]: testbed release detected to be: None 428s autopkgtest [11:44:47]: updating testbed package index (apt update) 428s Get:1 http://ftpmaster.internal/ubuntu plucky-proposed InRelease [73.9 kB] 429s Hit:2 http://ftpmaster.internal/ubuntu plucky InRelease 429s Hit:3 http://ftpmaster.internal/ubuntu plucky-updates InRelease 429s Hit:4 http://ftpmaster.internal/ubuntu plucky-security InRelease 429s Get:5 http://ftpmaster.internal/ubuntu plucky-proposed/main Sources [105 kB] 429s Get:6 http://ftpmaster.internal/ubuntu plucky-proposed/restricted Sources [9708 B] 429s Get:7 http://ftpmaster.internal/ubuntu plucky-proposed/universe Sources [737 kB] 429s Get:8 http://ftpmaster.internal/ubuntu plucky-proposed/multiverse Sources [17.2 kB] 429s Get:9 http://ftpmaster.internal/ubuntu plucky-proposed/main ppc64el Packages [173 kB] 429s Get:10 http://ftpmaster.internal/ubuntu plucky-proposed/restricted ppc64el Packages [756 B] 429s Get:11 http://ftpmaster.internal/ubuntu plucky-proposed/universe ppc64el Packages [794 kB] 429s Get:12 http://ftpmaster.internal/ubuntu plucky-proposed/multiverse ppc64el Packages [16.2 kB] 429s Fetched 1926 kB in 1s (1887 kB/s) 430s Reading package lists... 430s Reading package lists... 431s Building dependency tree... 431s Reading state information... 431s Calculating upgrade... 431s 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. 431s Reading package lists... 431s Building dependency tree... 431s Reading state information... 431s 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. 432s autopkgtest [11:44:51]: upgrading testbed (apt dist-upgrade and autopurge) 432s Reading package lists... 432s Building dependency tree... 432s Reading state information... 432s Calculating upgrade...Starting pkgProblemResolver with broken count: 0 432s Starting 2 pkgProblemResolver with broken count: 0 432s Done 433s Entering ResolveByKeep 433s 433s 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. 433s Reading package lists... 433s Building dependency tree... 433s Reading state information... 433s Starting pkgProblemResolver with broken count: 0 433s Starting 2 pkgProblemResolver with broken count: 0 433s Done 434s 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. 436s autopkgtest [11:44:55]: testbed running kernel: Linux 6.11.0-8-generic #8-Ubuntu SMP Mon Sep 16 13:49:23 UTC 2024 436s autopkgtest [11:44:55]: @@@@@@@@@@@@@@@@@@@@ apt-source slony1-2 440s Get:1 http://ftpmaster.internal/ubuntu plucky/universe slony1-2 2.2.11-4 (dsc) [2413 B] 440s Get:2 http://ftpmaster.internal/ubuntu plucky/universe slony1-2 2.2.11-4 (tar) [1465 kB] 440s Get:3 http://ftpmaster.internal/ubuntu plucky/universe slony1-2 2.2.11-4 (diff) [17.1 kB] 440s gpgv: Signature made Sun Jul 28 15:46:54 2024 UTC 440s gpgv: using RSA key 5C48FE6157F49179597087C64C5A6BAB12D2A7AE 440s gpgv: Can't check signature: No public key 440s dpkg-source: warning: cannot verify inline signature for ./slony1-2_2.2.11-4.dsc: no acceptable signature found 440s autopkgtest [11:44:59]: testing package slony1-2 version 2.2.11-4 441s autopkgtest [11:45:00]: build not needed 441s autopkgtest [11:45:00]: test load-functions: preparing testbed 441s Reading package lists... 442s Building dependency tree... 442s Reading state information... 442s Starting pkgProblemResolver with broken count: 0 442s Starting 2 pkgProblemResolver with broken count: 0 442s Done 442s The following NEW packages will be installed: 442s libjson-perl libpq5 libxslt1.1 postgresql-16 postgresql-16-slony1-2 442s postgresql-client-16 postgresql-client-common postgresql-common slony1-2-bin 442s slony1-2-doc ssl-cert 442s 0 upgraded, 11 newly installed, 0 to remove and 0 not upgraded. 442s Need to get 19.3 MB of archives. 442s After this operation, 66.5 MB of additional disk space will be used. 442s Get:1 http://ftpmaster.internal/ubuntu plucky/main ppc64el libjson-perl all 4.10000-1 [81.9 kB] 442s Get:2 http://ftpmaster.internal/ubuntu plucky/main ppc64el postgresql-client-common all 262 [36.7 kB] 442s Get:3 http://ftpmaster.internal/ubuntu plucky/main ppc64el ssl-cert all 1.1.3ubuntu1 [18.7 kB] 442s Get:4 http://ftpmaster.internal/ubuntu plucky/main ppc64el postgresql-common all 262 [162 kB] 442s Get:5 http://ftpmaster.internal/ubuntu plucky-proposed/main ppc64el libpq5 ppc64el 17.2-1build2 [173 kB] 443s Get:6 http://ftpmaster.internal/ubuntu plucky/main ppc64el libxslt1.1 ppc64el 1.1.39-0exp1ubuntu2 [191 kB] 443s Get:7 http://ftpmaster.internal/ubuntu plucky/main ppc64el postgresql-client-16 ppc64el 16.4-3 [1400 kB] 443s Get:8 http://ftpmaster.internal/ubuntu plucky/main ppc64el postgresql-16 ppc64el 16.4-3 [16.6 MB] 446s Get:9 http://ftpmaster.internal/ubuntu plucky/universe ppc64el postgresql-16-slony1-2 ppc64el 2.2.11-4 [24.3 kB] 446s Get:10 http://ftpmaster.internal/ubuntu plucky/universe ppc64el slony1-2-bin ppc64el 2.2.11-4 [238 kB] 446s Get:11 http://ftpmaster.internal/ubuntu plucky/universe ppc64el slony1-2-doc all 2.2.11-4 [328 kB] 446s Preconfiguring packages ... 447s Fetched 19.3 MB in 4s (4615 kB/s) 447s Selecting previously unselected package libjson-perl. 447s (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 74025 files and directories currently installed.) 447s Preparing to unpack .../00-libjson-perl_4.10000-1_all.deb ... 447s Unpacking libjson-perl (4.10000-1) ... 447s Selecting previously unselected package postgresql-client-common. 447s Preparing to unpack .../01-postgresql-client-common_262_all.deb ... 447s Unpacking postgresql-client-common (262) ... 447s Selecting previously unselected package ssl-cert. 447s Preparing to unpack .../02-ssl-cert_1.1.3ubuntu1_all.deb ... 447s Unpacking ssl-cert (1.1.3ubuntu1) ... 447s Selecting previously unselected package postgresql-common. 447s Preparing to unpack .../03-postgresql-common_262_all.deb ... 447s Adding 'diversion of /usr/bin/pg_config to /usr/bin/pg_config.libpq-dev by postgresql-common' 447s Unpacking postgresql-common (262) ... 447s Selecting previously unselected package libpq5:ppc64el. 447s Preparing to unpack .../04-libpq5_17.2-1build2_ppc64el.deb ... 447s Unpacking libpq5:ppc64el (17.2-1build2) ... 447s Selecting previously unselected package libxslt1.1:ppc64el. 447s Preparing to unpack .../05-libxslt1.1_1.1.39-0exp1ubuntu2_ppc64el.deb ... 447s Unpacking libxslt1.1:ppc64el (1.1.39-0exp1ubuntu2) ... 447s Selecting previously unselected package postgresql-client-16. 447s Preparing to unpack .../06-postgresql-client-16_16.4-3_ppc64el.deb ... 447s Unpacking postgresql-client-16 (16.4-3) ... 447s Selecting previously unselected package postgresql-16. 447s Preparing to unpack .../07-postgresql-16_16.4-3_ppc64el.deb ... 447s Unpacking postgresql-16 (16.4-3) ... 447s Selecting previously unselected package postgresql-16-slony1-2. 447s Preparing to unpack .../08-postgresql-16-slony1-2_2.2.11-4_ppc64el.deb ... 447s Unpacking postgresql-16-slony1-2 (2.2.11-4) ... 447s Selecting previously unselected package slony1-2-bin. 447s Preparing to unpack .../09-slony1-2-bin_2.2.11-4_ppc64el.deb ... 447s Unpacking slony1-2-bin (2.2.11-4) ... 447s Selecting previously unselected package slony1-2-doc. 448s Preparing to unpack .../10-slony1-2-doc_2.2.11-4_all.deb ... 448s Unpacking slony1-2-doc (2.2.11-4) ... 448s Setting up postgresql-client-common (262) ... 448s Setting up libpq5:ppc64el (17.2-1build2) ... 448s Setting up ssl-cert (1.1.3ubuntu1) ... 448s Created symlink '/etc/systemd/system/multi-user.target.wants/ssl-cert.service' → '/usr/lib/systemd/system/ssl-cert.service'. 448s Setting up libjson-perl (4.10000-1) ... 448s Setting up libxslt1.1:ppc64el (1.1.39-0exp1ubuntu2) ... 448s Setting up slony1-2-doc (2.2.11-4) ... 448s Setting up postgresql-client-16 (16.4-3) ... 449s update-alternatives: using /usr/share/postgresql/16/man/man1/psql.1.gz to provide /usr/share/man/man1/psql.1.gz (psql.1.gz) in auto mode 449s Setting up postgresql-common (262) ... 449s Creating config file /etc/postgresql-common/createcluster.conf with new version 449s Building PostgreSQL dictionaries from installed myspell/hunspell packages... 449s Removing obsolete dictionary files: 450s Created symlink '/etc/systemd/system/multi-user.target.wants/postgresql.service' → '/usr/lib/systemd/system/postgresql.service'. 450s Setting up slony1-2-bin (2.2.11-4) ... 451s Setting up postgresql-16 (16.4-3) ... 451s Creating new PostgreSQL cluster 16/main ... 451s /usr/lib/postgresql/16/bin/initdb -D /var/lib/postgresql/16/main --auth-local peer --auth-host scram-sha-256 --no-instructions 451s The files belonging to this database system will be owned by user "postgres". 451s This user must also own the server process. 451s 451s The database cluster will be initialized with locale "C.UTF-8". 451s The default database encoding has accordingly been set to "UTF8". 451s The default text search configuration will be set to "english". 451s 451s Data page checksums are disabled. 451s 451s fixing permissions on existing directory /var/lib/postgresql/16/main ... ok 451s creating subdirectories ... ok 451s selecting dynamic shared memory implementation ... posix 451s selecting default max_connections ... 100 451s selecting default shared_buffers ... 128MB 451s selecting default time zone ... Etc/UTC 451s creating configuration files ... ok 451s running bootstrap script ... ok 452s performing post-bootstrap initialization ... ok 452s syncing data to disk ... ok 455s Setting up postgresql-16-slony1-2 (2.2.11-4) ... 455s Processing triggers for libc-bin (2.40-4ubuntu1) ... 455s Processing triggers for man-db (2.13.0-1) ... 458s autopkgtest [11:45:17]: test load-functions: [----------------------- 458s ### PostgreSQL 16 psql ### 458s Creating new PostgreSQL cluster 16/regress ... 461s create table public.sl_node ( 461s no_id int4, 461s no_active bool, 461s no_comment text, 461s no_failed bool, 461s CONSTRAINT "sl_node-pkey" 461s PRIMARY KEY (no_id) 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s comment on table public.sl_node is 'Holds the list of nodes associated with this namespace.'; 461s COMMENT 461s comment on column public.sl_node.no_id is 'The unique ID number for the node'; 461s COMMENT 461s comment on column public.sl_node.no_active is 'Is the node active in replication yet?'; 461s COMMENT 461s comment on column public.sl_node.no_comment is 'A human-oriented description of the node'; 461s COMMENT 461s create table public.sl_nodelock ( 461s nl_nodeid int4, 461s nl_conncnt serial, 461s nl_backendpid int4, 461s CONSTRAINT "sl_nodelock-pkey" 461s PRIMARY KEY (nl_nodeid, nl_conncnt) 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s comment on table public.sl_nodelock is 'Used to prevent multiple slon instances and to identify the backends to kill in terminateNodeConnections().'; 461s COMMENT 461s comment on column public.sl_nodelock.nl_nodeid is 'Clients node_id'; 461s COMMENT 461s comment on column public.sl_nodelock.nl_conncnt is 'Clients connection number'; 461s COMMENT 461s comment on column public.sl_nodelock.nl_backendpid is 'PID of database backend owning this lock'; 461s COMMENT 461s create table public.sl_set ( 461s set_id int4, 461s set_origin int4, 461s set_locked bigint, 461s set_comment text, 461s CONSTRAINT "sl_set-pkey" 461s PRIMARY KEY (set_id), 461s CONSTRAINT "set_origin-no_id-ref" 461s FOREIGN KEY (set_origin) 461s REFERENCES public.sl_node (no_id) 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s comment on table public.sl_set is 'Holds definitions of replication sets.'; 461s COMMENT 461s comment on column public.sl_set.set_id is 'A unique ID number for the set.'; 461s COMMENT 461s comment on column public.sl_set.set_origin is 461s 'The ID number of the source node for the replication set.'; 461s COMMENT 461s comment on column public.sl_set.set_locked is 'Transaction ID where the set was locked.'; 461s COMMENT 461s comment on column public.sl_set.set_comment is 'A human-oriented description of the set.'; 461s COMMENT 461s create table public.sl_setsync ( 461s ssy_setid int4, 461s ssy_origin int4, 461s ssy_seqno int8, 461s ssy_snapshot "pg_catalog".txid_snapshot, 461s ssy_action_list text, 461s CONSTRAINT "sl_setsync-pkey" 461s PRIMARY KEY (ssy_setid), 461s CONSTRAINT "ssy_setid-set_id-ref" 461s FOREIGN KEY (ssy_setid) 461s REFERENCES public.sl_set (set_id), 461s CONSTRAINT "ssy_origin-no_id-ref" 461s FOREIGN KEY (ssy_origin) 461s REFERENCES public.sl_node (no_id) 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s comment on table public.sl_setsync is 'SYNC information'; 461s COMMENT 461s comment on column public.sl_setsync.ssy_setid is 'ID number of the replication set'; 461s COMMENT 461s comment on column public.sl_setsync.ssy_origin is 'ID number of the node'; 461s COMMENT 461s comment on column public.sl_setsync.ssy_seqno is 'Slony-I sequence number'; 461s COMMENT 461s comment on column public.sl_setsync.ssy_snapshot is 'TXID in provider system seen by the event'; 461s COMMENT 461s comment on column public.sl_setsync.ssy_action_list is 'action list used during the subscription process. At the time a subscriber copies over data from the origin, it sees all tables in a state somewhere between two SYNC events. Therefore this list must contains all log_actionseqs that are visible at that time, whose operations have therefore already been included in the data copied at the time the initial data copy is done. Those actions may therefore be filtered out of the first SYNC done after subscribing.'; 461s COMMENT 461s create table public.sl_table ( 461s tab_id int4, 461s tab_reloid oid UNIQUE NOT NULL, 461s tab_relname name NOT NULL, 461s tab_nspname name NOT NULL, 461s tab_set int4, 461s tab_idxname name NOT NULL, 461s tab_altered boolean NOT NULL, 461s tab_comment text, 461s CONSTRAINT "sl_table-pkey" 461s PRIMARY KEY (tab_id), 461s CONSTRAINT "tab_set-set_id-ref" 461s FOREIGN KEY (tab_set) 461s REFERENCES public.sl_set (set_id) 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s comment on table public.sl_table is 'Holds information about the tables being replicated.'; 461s COMMENT 461s comment on column public.sl_table.tab_id is 'Unique key for Slony-I to use to identify the table'; 461s COMMENT 461s comment on column public.sl_table.tab_reloid is 'The OID of the table in pg_catalog.pg_class.oid'; 461s COMMENT 461s comment on column public.sl_table.tab_relname is 'The name of the table in pg_catalog.pg_class.relname used to recover from a dump/restore cycle'; 461s COMMENT 461s comment on column public.sl_table.tab_nspname is 'The name of the schema in pg_catalog.pg_namespace.nspname used to recover from a dump/restore cycle'; 461s COMMENT 461s comment on column public.sl_table.tab_set is 'ID of the replication set the table is in'; 461s COMMENT 461s comment on column public.sl_table.tab_idxname is 'The name of the primary index of the table'; 461s COMMENT 461s comment on column public.sl_table.tab_altered is 'Has the table been modified for replication?'; 461s COMMENT 461s comment on column public.sl_table.tab_comment is 'Human-oriented description of the table'; 461s COMMENT 461s create table public.sl_sequence ( 461s seq_id int4, 461s seq_reloid oid UNIQUE NOT NULL, 461s seq_relname name NOT NULL, 461s seq_nspname name NOT NULL, 461s seq_set int4, 461s seq_comment text, 461s CONSTRAINT "sl_sequence-pkey" 461s PRIMARY KEY (seq_id), 461s CONSTRAINT "seq_set-set_id-ref" 461s FOREIGN KEY (seq_set) 461s REFERENCES public.sl_set (set_id) 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s comment on table public.sl_sequence is 'Similar to sl_table, each entry identifies a sequence being replicated.'; 461s COMMENT 461s comment on column public.sl_sequence.seq_id is 'An internally-used ID for Slony-I to use in its sequencing of updates'; 461s COMMENT 461s comment on column public.sl_sequence.seq_reloid is 'The OID of the sequence object'; 461s COMMENT 461s comment on column public.sl_sequence.seq_relname is 'The name of the sequence in pg_catalog.pg_class.relname used to recover from a dump/restore cycle'; 461s COMMENT 461s comment on column public.sl_sequence.seq_nspname is 'The name of the schema in pg_catalog.pg_namespace.nspname used to recover from a dump/restore cycle'; 461s COMMENT 461s comment on column public.sl_sequence.seq_set is 'Indicates which replication set the object is in'; 461s COMMENT 461s comment on column public.sl_sequence.seq_comment is 'A human-oriented comment'; 461s COMMENT 461s create table public.sl_path ( 461s pa_server int4, 461s pa_client int4, 461s pa_conninfo text NOT NULL, 461s pa_connretry int4, 461s CONSTRAINT "sl_path-pkey" 461s PRIMARY KEY (pa_server, pa_client), 461s CONSTRAINT "pa_server-no_id-ref" 461s FOREIGN KEY (pa_server) 461s REFERENCES public.sl_node (no_id), 461s CONSTRAINT "pa_client-no_id-ref" 461s FOREIGN KEY (pa_client) 461s REFERENCES public.sl_node (no_id) 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s comment on table public.sl_path is 'Holds connection information for the paths between nodes, and the synchronisation delay'; 461s COMMENT 461s comment on column public.sl_path.pa_server is 'The Node ID # (from sl_node.no_id) of the data source'; 461s COMMENT 461s comment on column public.sl_path.pa_client is 'The Node ID # (from sl_node.no_id) of the data target'; 461s COMMENT 461s comment on column public.sl_path.pa_conninfo is 'The PostgreSQL connection string used to connect to the source node.'; 461s COMMENT 461s comment on column public.sl_path.pa_connretry is 'The synchronisation delay, in seconds'; 461s COMMENT 461s create table public.sl_listen ( 461s li_origin int4, 461s li_provider int4, 461s li_receiver int4, 461s CONSTRAINT "sl_listen-pkey" 461s PRIMARY KEY (li_origin, li_provider, li_receiver), 461s CONSTRAINT "li_origin-no_id-ref" 461s FOREIGN KEY (li_origin) 461s REFERENCES public.sl_node (no_id), 461s CONSTRAINT "sl_listen-sl_path-ref" 461s FOREIGN KEY (li_provider, li_receiver) 461s REFERENCES public.sl_path (pa_server, pa_client) 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s comment on table public.sl_listen is 'Indicates how nodes listen to events from other nodes in the Slony-I network.'; 461s COMMENT 461s comment on column public.sl_listen.li_origin is 'The ID # (from sl_node.no_id) of the node this listener is operating on'; 461s COMMENT 461s comment on column public.sl_listen.li_provider is 'The ID # (from sl_node.no_id) of the source node for this listening event'; 461s COMMENT 461s comment on column public.sl_listen.li_receiver is 'The ID # (from sl_node.no_id) of the target node for this listening event'; 461s COMMENT 461s create table public.sl_subscribe ( 461s sub_set int4, 461s sub_provider int4, 461s sub_receiver int4, 461s sub_forward bool, 461s sub_active bool, 461s CONSTRAINT "sl_subscribe-pkey" 461s PRIMARY KEY (sub_receiver, sub_set), 461s CONSTRAINT "sl_subscribe-sl_path-ref" 461s FOREIGN KEY (sub_provider, sub_receiver) 461s REFERENCES public.sl_path (pa_server, pa_client), 461s CONSTRAINT "sub_set-set_id-ref" 461s FOREIGN KEY (sub_set) 461s REFERENCES public.sl_set (set_id) 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s comment on table public.sl_subscribe is 'Holds a list of subscriptions on sets'; 461s COMMENT 461s comment on column public.sl_subscribe.sub_set is 'ID # (from sl_set) of the set being subscribed to'; 461s COMMENT 461s comment on column public.sl_subscribe.sub_provider is 'ID# (from sl_node) of the node providing data'; 461s COMMENT 461s comment on column public.sl_subscribe.sub_receiver is 'ID# (from sl_node) of the node receiving data from the provider'; 461s COMMENT 461s comment on column public.sl_subscribe.sub_forward is 'Does this provider keep data in sl_log_1/sl_log_2 to allow it to be a provider for other nodes?'; 461s COMMENT 461s comment on column public.sl_subscribe.sub_active is 'Has this subscription been activated? This is not set on the subscriber until AFTER the subscriber has received COPY data from the provider'; 461s COMMENT 461s create table public.sl_event ( 461s ev_origin int4, 461s ev_seqno int8, 461s ev_timestamp timestamptz, 461s ev_snapshot "pg_catalog".txid_snapshot, 461s ev_type text, 461s ev_data1 text, 461s ev_data2 text, 461s ev_data3 text, 461s ev_data4 text, 461s ev_data5 text, 461s ev_data6 text, 461s ev_data7 text, 461s ev_data8 text, 461s CONSTRAINT "sl_event-pkey" 461s PRIMARY KEY (ev_origin, ev_seqno) 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s comment on table public.sl_event is 'Holds information about replication events. After a period of time, Slony removes old confirmed events from both this table and the sl_confirm table.'; 461s COMMENT 461s comment on column public.sl_event.ev_origin is 'The ID # (from sl_node.no_id) of the source node for this event'; 461s COMMENT 461s comment on column public.sl_event.ev_seqno is 'The ID # for the event'; 461s COMMENT 461s comment on column public.sl_event.ev_timestamp is 'When this event record was created'; 461s COMMENT 461s comment on column public.sl_event.ev_snapshot is 'TXID snapshot on provider node for this event'; 461s COMMENT 461s comment on column public.sl_event.ev_seqno is 'The ID # for the event'; 461s COMMENT 461s comment on column public.sl_event.ev_type is 'The type of event this record is for. 461s SYNC = Synchronise 461s STORE_NODE = 461s ENABLE_NODE = 461s DROP_NODE = 461s STORE_PATH = 461s DROP_PATH = 461s STORE_LISTEN = 461s DROP_LISTEN = 461s STORE_SET = 461s DROP_SET = 461s MERGE_SET = 461s SET_ADD_TABLE = 461s SET_ADD_SEQUENCE = 461s STORE_TRIGGER = 461s DROP_TRIGGER = 461s MOVE_SET = 461s ACCEPT_SET = 461s SET_DROP_TABLE = 461s SET_DROP_SEQUENCE = 461s SET_MOVE_TABLE = 461s SET_MOVE_SEQUENCE = 461s FAILOVER_SET = 461s SUBSCRIBE_SET = 461s ENABLE_SUBSCRIPTION = 461s UNSUBSCRIBE_SET = 461s DDL_SCRIPT = 461s ADJUST_SEQ = 461s RESET_CONFIG = 461s '; 461s COMMENT 461s comment on column public.sl_event.ev_data1 is 'Data field containing an argument needed to process the event'; 461s COMMENT 461s comment on column public.sl_event.ev_data2 is 'Data field containing an argument needed to process the event'; 461s COMMENT 461s comment on column public.sl_event.ev_data3 is 'Data field containing an argument needed to process the event'; 461s COMMENT 461s comment on column public.sl_event.ev_data4 is 'Data field containing an argument needed to process the event'; 461s COMMENT 461s comment on column public.sl_event.ev_data5 is 'Data field containing an argument needed to process the event'; 461s COMMENT 461s comment on column public.sl_event.ev_data6 is 'Data field containing an argument needed to process the event'; 461s COMMENT 461s comment on column public.sl_event.ev_data7 is 'Data field containing an argument needed to process the event'; 461s COMMENT 461s comment on column public.sl_event.ev_data8 is 'Data field containing an argument needed to process the event'; 461s COMMENT 461s create table public.sl_confirm ( 461s con_origin int4, 461s con_received int4, 461s con_seqno int8, 461s con_timestamp timestamptz DEFAULT timeofday()::timestamptz 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s comment on table public.sl_confirm is 'Holds confirmation of replication events. After a period of time, Slony removes old confirmed events from both this table and the sl_event table.'; 461s COMMENT 461s comment on column public.sl_confirm.con_origin is 'The ID # (from sl_node.no_id) of the source node for this event'; 461s COMMENT 461s comment on column public.sl_confirm.con_seqno is 'The ID # for the event'; 461s COMMENT 461s comment on column public.sl_confirm.con_timestamp is 'When this event was confirmed'; 461s COMMENT 461s create index sl_confirm_idx1 on public.sl_confirm 461s (con_origin, con_received, con_seqno); 461s CREATE INDEX 461s create index sl_confirm_idx2 on public.sl_confirm 461s (con_received, con_seqno); 461s CREATE INDEX 461s create table public.sl_seqlog ( 461s seql_seqid int4, 461s seql_origin int4, 461s seql_ev_seqno int8, 461s seql_last_value int8 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s comment on table public.sl_seqlog is 'Log of Sequence updates'; 461s COMMENT 461s comment on column public.sl_seqlog.seql_seqid is 'Sequence ID'; 461s COMMENT 461s comment on column public.sl_seqlog.seql_origin is 'Publisher node at which the sequence originates'; 461s COMMENT 461s comment on column public.sl_seqlog.seql_ev_seqno is 'Slony-I Event with which this sequence update is associated'; 461s COMMENT 461s comment on column public.sl_seqlog.seql_last_value is 'Last value published for this sequence'; 461s COMMENT 461s create index sl_seqlog_idx on public.sl_seqlog 461s (seql_origin, seql_ev_seqno, seql_seqid); 461s CREATE INDEX 461s create function public.sequenceLastValue(p_seqname text) returns int8 461s as $$ 461s declare 461s v_seq_row record; 461s begin 461s for v_seq_row in execute 'select last_value from ' || public.slon_quote_input(p_seqname) 461s loop 461s return v_seq_row.last_value; 461s end loop; 461s 461s -- not reached 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.sequenceLastValue(p_seqname text) is 461s 'sequenceLastValue(p_seqname) 461s 461s Utility function used in sl_seqlastvalue view to compactly get the 461s last value from the requested sequence.'; 461s COMMENT 461s create table public.sl_log_1 ( 461s log_origin int4, 461s log_txid bigint, 461s log_tableid int4, 461s log_actionseq int8, 461s log_tablenspname text, 461s log_tablerelname text, 461s log_cmdtype "char", 461s log_cmdupdncols int4, 461s log_cmdargs text[] 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s create index sl_log_1_idx1 on public.sl_log_1 461s (log_origin, log_txid, log_actionseq); 461s CREATE INDEX 461s comment on table public.sl_log_1 is 'Stores each change to be propagated to subscriber nodes'; 461s COMMENT 461s comment on column public.sl_log_1.log_origin is 'Origin node from which the change came'; 461s COMMENT 461s comment on column public.sl_log_1.log_txid is 'Transaction ID on the origin node'; 461s COMMENT 461s comment on column public.sl_log_1.log_tableid is 'The table ID (from sl_table.tab_id) that this log entry is to affect'; 461s COMMENT 461s comment on column public.sl_log_1.log_actionseq is 'The sequence number in which actions will be applied on replicas'; 461s COMMENT 461s comment on column public.sl_log_1.log_tablenspname is 'The schema name of the table affected'; 461s COMMENT 461s comment on column public.sl_log_1.log_tablerelname is 'The table name of the table affected'; 461s COMMENT 461s comment on column public.sl_log_1.log_cmdtype is 'Replication action to take. U = Update, I = Insert, D = DELETE, T = TRUNCATE'; 461s COMMENT 461s comment on column public.sl_log_1.log_cmdupdncols is 'For cmdtype=U the number of updated columns in cmdargs'; 461s COMMENT 461s comment on column public.sl_log_1.log_cmdargs is 'The data needed to perform the log action on the replica'; 461s COMMENT 461s create table public.sl_log_2 ( 461s log_origin int4, 461s log_txid bigint, 461s log_tableid int4, 461s log_actionseq int8, 461s log_tablenspname text, 461s log_tablerelname text, 461s log_cmdtype "char", 461s log_cmdupdncols int4, 461s log_cmdargs text[] 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s create index sl_log_2_idx1 on public.sl_log_2 461s (log_origin, log_txid, log_actionseq); 461s CREATE INDEX 461s comment on table public.sl_log_2 is 'Stores each change to be propagated to subscriber nodes'; 461s COMMENT 461s comment on column public.sl_log_2.log_origin is 'Origin node from which the change came'; 461s COMMENT 461s comment on column public.sl_log_2.log_txid is 'Transaction ID on the origin node'; 461s COMMENT 461s comment on column public.sl_log_2.log_tableid is 'The table ID (from sl_table.tab_id) that this log entry is to affect'; 461s COMMENT 461s comment on column public.sl_log_2.log_actionseq is 'The sequence number in which actions will be applied on replicas'; 461s COMMENT 461s comment on column public.sl_log_2.log_tablenspname is 'The schema name of the table affected'; 461s COMMENT 461s comment on column public.sl_log_2.log_tablerelname is 'The table name of the table affected'; 461s COMMENT 461s comment on column public.sl_log_2.log_cmdtype is 'Replication action to take. U = Update, I = Insert, D = DELETE, T = TRUNCATE'; 461s COMMENT 461s comment on column public.sl_log_2.log_cmdupdncols is 'For cmdtype=U the number of updated columns in cmdargs'; 461s COMMENT 461s comment on column public.sl_log_2.log_cmdargs is 'The data needed to perform the log action on the replica'; 461s COMMENT 461s create table public.sl_log_script ( 461s log_origin int4, 461s log_txid bigint, 461s log_actionseq int8, 461s log_cmdtype "char", 461s log_cmdargs text[] 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s create index sl_log_script_idx1 on public.sl_log_script 461s (log_origin, log_txid, log_actionseq); 461s CREATE INDEX 461s comment on table public.sl_log_script is 'Captures SQL script queries to be propagated to subscriber nodes'; 461s COMMENT 461s comment on column public.sl_log_script.log_origin is 'Origin name from which the change came'; 461s COMMENT 461s comment on column public.sl_log_script.log_txid is 'Transaction ID on the origin node'; 461s COMMENT 461s comment on column public.sl_log_script.log_actionseq is 'The sequence number in which actions will be applied on replicas'; 461s COMMENT 461s comment on column public.sl_log_2.log_cmdtype is 'Replication action to take. S = Script statement, s = Script complete'; 461s COMMENT 461s comment on column public.sl_log_script.log_cmdargs is 'The DDL statement, optionally followed by selected nodes to execute it on.'; 461s COMMENT 461s create table public.sl_registry ( 461s reg_key text primary key, 461s reg_int4 int4, 461s reg_text text, 461s reg_timestamp timestamptz 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s comment on table public.sl_registry is 'Stores miscellaneous runtime data'; 461s COMMENT 461s comment on column public.sl_registry.reg_key is 'Unique key of the runtime option'; 461s COMMENT 461s comment on column public.sl_registry.reg_int4 is 'Option value if type int4'; 461s COMMENT 461s comment on column public.sl_registry.reg_text is 'Option value if type text'; 461s COMMENT 461s comment on column public.sl_registry.reg_timestamp is 'Option value if type timestamp'; 461s COMMENT 461s create table public.sl_apply_stats ( 461s as_origin int4, 461s as_num_insert int8, 461s as_num_update int8, 461s as_num_delete int8, 461s as_num_truncate int8, 461s as_num_script int8, 461s as_num_total int8, 461s as_duration interval, 461s as_apply_first timestamptz, 461s as_apply_last timestamptz, 461s as_cache_prepare int8, 461s as_cache_hit int8, 461s as_cache_evict int8, 461s as_cache_prepare_max int8 461s ) WITHOUT OIDS; 461s CREATE TABLE 461s create index sl_apply_stats_idx1 on public.sl_apply_stats 461s (as_origin); 461s CREATE INDEX 461s comment on table public.sl_apply_stats is 'Local SYNC apply statistics (running totals)'; 461s COMMENT 461s comment on column public.sl_apply_stats.as_origin is 'Origin of the SYNCs'; 461s COMMENT 461s comment on column public.sl_apply_stats.as_num_insert is 'Number of INSERT operations performed'; 461s COMMENT 461s comment on column public.sl_apply_stats.as_num_update is 'Number of UPDATE operations performed'; 461s COMMENT 461s comment on column public.sl_apply_stats.as_num_delete is 'Number of DELETE operations performed'; 461s COMMENT 461s comment on column public.sl_apply_stats.as_num_truncate is 'Number of TRUNCATE operations performed'; 461s COMMENT 461s comment on column public.sl_apply_stats.as_num_script is 'Number of DDL operations performed'; 461s COMMENT 461s comment on column public.sl_apply_stats.as_num_total is 'Total number of operations'; 461s COMMENT 461s comment on column public.sl_apply_stats.as_duration is 'Processing time'; 461s COMMENT 461s comment on column public.sl_apply_stats.as_apply_first is 'Timestamp of first recorded SYNC'; 461s COMMENT 461s comment on column public.sl_apply_stats.as_apply_last is 'Timestamp of most recent recorded SYNC'; 461s COMMENT 461s comment on column public.sl_apply_stats.as_cache_evict is 'Number of apply query cache evict operations'; 461s COMMENT 461s comment on column public.sl_apply_stats.as_cache_prepare_max is 'Maximum number of apply queries prepared in one SYNC group'; 461s COMMENT 461s create view public.sl_seqlastvalue as 461s select SQ.seq_id, SQ.seq_set, SQ.seq_reloid, 461s S.set_origin as seq_origin, 461s public.sequenceLastValue( 461s "pg_catalog".quote_ident(PGN.nspname) || '.' || 461s "pg_catalog".quote_ident(PGC.relname)) as seq_last_value 461s from public.sl_sequence SQ, public.sl_set S, 461s "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN 461s where S.set_id = SQ.seq_set 461s and PGC.oid = SQ.seq_reloid and PGN.oid = PGC.relnamespace; 461s CREATE VIEW 461s create view public.sl_failover_targets as 461s select set_id, 461s set_origin as set_origin, 461s sub1.sub_receiver as backup_id 461s FROM 461s public.sl_subscribe sub1 461s ,public.sl_set set1 461s where 461s sub1.sub_set=set_id 461s and sub1.sub_forward=true 461s --exclude candidates where the set_origin 461s --has a path a node but the failover 461s --candidate has no path to that node 461s and sub1.sub_receiver not in 461s (select p1.pa_client from 461s public.sl_path p1 461s left outer join public.sl_path p2 on 461s (p2.pa_client=p1.pa_client 461s and p2.pa_server=sub1.sub_receiver) 461s where p2.pa_client is null 461s and p1.pa_server=set_origin 461s and p1.pa_client<>sub1.sub_receiver 461s ) 461s and sub1.sub_provider=set_origin 461s --exclude any subscribers that are not 461s --direct subscribers of all sets on the 461s --origin 461s and sub1.sub_receiver not in 461s (select direct_recv.sub_receiver 461s from 461s 461s (--all direct receivers of the first set 461s select subs2.sub_receiver 461s from public.sl_subscribe subs2 461s where subs2.sub_provider=set1.set_origin 461s and subs2.sub_set=set1.set_id) as 461s direct_recv 461s inner join 461s (--all other sets from the origin 461s select set_id from public.sl_set set2 461s where set2.set_origin=set1.set_origin 461s and set2.set_id<>sub1.sub_set) 461s as othersets on(true) 461s left outer join public.sl_subscribe subs3 461s on(subs3.sub_set=othersets.set_id 461s and subs3.sub_forward=true 461s and subs3.sub_provider=set1.set_origin 461s and direct_recv.sub_receiver=subs3.sub_receiver) 461s where subs3.sub_receiver is null 461s ); 461s CREATE VIEW 461s create sequence public.sl_local_node_id 461s MINVALUE -1; 461s CREATE SEQUENCE 461s SELECT setval('public.sl_local_node_id', -1); 461s setval 461s -------- 461s -1 461s (1 row) 461s 461s comment on sequence public.sl_local_node_id is 'The local node ID is initialized to -1, meaning that this node is not initialized yet.'; 461s COMMENT 461s create sequence public.sl_event_seq; 461s CREATE SEQUENCE 461s comment on sequence public.sl_event_seq is 'The sequence for numbering events originating from this node.'; 461s COMMENT 461s select setval('public.sl_event_seq', 5000000000); 461s setval 461s ------------ 461s 5000000000 461s (1 row) 461s 461s create sequence public.sl_action_seq; 461s CREATE SEQUENCE 461s comment on sequence public.sl_action_seq is 'The sequence to number statements in the transaction logs, so that the replication engines can figure out the "agreeable" order of statements.'; 461s COMMENT 461s create sequence public.sl_log_status 461s MINVALUE 0 MAXVALUE 3; 461s CREATE SEQUENCE 461s SELECT setval('public.sl_log_status', 0); 461s setval 461s -------- 461s 0 461s (1 row) 461s 461s comment on sequence public.sl_log_status is ' 461s Bit 0x01 determines the currently active log table 461s Bit 0x02 tells if the engine needs to read both logs 461s after switching until the old log is clean and truncated. 461s 461s Possible values: 461s 0 sl_log_1 active, sl_log_2 clean 461s 1 sl_log_2 active, sl_log_1 clean 461s 2 sl_log_1 active, sl_log_2 unknown - cleanup 461s 3 sl_log_2 active, sl_log_1 unknown - cleanup 461s 461s This is not yet in use. 461s '; 461s COMMENT 461s create table public.sl_config_lock ( 461s dummy integer 461s ); 461s CREATE TABLE 461s comment on table public.sl_config_lock is 'This table exists solely to prevent overlapping execution of configuration change procedures and the resulting possible deadlocks. 461s '; 461s COMMENT 461s comment on column public.sl_config_lock.dummy is 'No data ever goes in this table so the contents never matter. Indeed, this column does not really need to exist.'; 461s COMMENT 461s create table public.sl_event_lock ( 461s dummy integer 461s ); 461s CREATE TABLE 461s comment on table public.sl_event_lock is 'This table exists solely to prevent multiple connections from concurrently creating new events and perhaps getting them out of order.'; 461s COMMENT 461s comment on column public.sl_event_lock.dummy is 'No data ever goes in this table so the contents never matter. Indeed, this column does not really need to exist.'; 461s COMMENT 461s create table public.sl_archive_counter ( 461s ac_num bigint, 461s ac_timestamp timestamptz 461s ) without oids; 461s CREATE TABLE 461s comment on table public.sl_archive_counter is 'Table used to generate the log shipping archive number. 461s '; 461s COMMENT 461s comment on column public.sl_archive_counter.ac_num is 'Counter of SYNC ID used in log shipping as the archive number'; 461s COMMENT 461s comment on column public.sl_archive_counter.ac_timestamp is 'Time at which the archive log was generated on the subscriber'; 461s COMMENT 461s insert into public.sl_archive_counter (ac_num, ac_timestamp) 461s values (0, 'epoch'::timestamptz); 461s INSERT 0 1 461s create table public.sl_components ( 461s co_actor text not null primary key, 461s co_pid integer not null, 461s co_node integer not null, 461s co_connection_pid integer not null, 461s co_activity text, 461s co_starttime timestamptz not null, 461s co_event bigint, 461s co_eventtype text 461s ) without oids; 461s CREATE TABLE 461s comment on table public.sl_components is 'Table used to monitor what various slon/slonik components are doing'; 461s COMMENT 461s comment on column public.sl_components.co_actor is 'which component am I?'; 461s COMMENT 461s comment on column public.sl_components.co_pid is 'my process/thread PID on node where slon runs'; 461s COMMENT 461s comment on column public.sl_components.co_node is 'which node am I servicing?'; 461s COMMENT 461s comment on column public.sl_components.co_connection_pid is 'PID of database connection being used on database server'; 461s COMMENT 461s comment on column public.sl_components.co_activity is 'activity that I am up to'; 461s COMMENT 461s comment on column public.sl_components.co_starttime is 'when did my activity begin? (timestamp reported as per slon process on server running slon)'; 461s COMMENT 461s comment on column public.sl_components.co_eventtype is 'what kind of event am I processing? (commonly n/a for event loop main threads)'; 461s COMMENT 461s comment on column public.sl_components.co_event is 'which event have I started processing?'; 461s NOTICE: checked validity of cluster main namespace - OK! 461s COMMENT 461s CREATE OR replace function public.agg_text_sum(txt_before TEXT, txt_new TEXT) RETURNS TEXT AS 461s $BODY$ 461s DECLARE 461s c_delim text; 461s BEGIN 461s c_delim = ','; 461s IF (txt_before IS NULL or txt_before='') THEN 461s RETURN txt_new; 461s END IF; 461s RETURN txt_before || c_delim || txt_new; 461s END; 461s $BODY$ 461s LANGUAGE plpgsql; 461s CREATE FUNCTION 461s comment on function public.agg_text_sum(text,text) is 461s 'An accumulator function used by the slony string_agg function to 461s aggregate rows into a string'; 461s COMMENT 461s CREATE AGGREGATE public.string_agg(text) ( 461s SFUNC=public.agg_text_sum, 461s STYPE=text, 461s INITCOND='' 461s ); 461s CREATE AGGREGATE 461s grant usage on schema public to public; 461s GRANT 461s create or replace function public.createEvent (p_cluster_name name, p_event_type text) 461s returns bigint 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__createEvent' 461s language C 461s called on null input; 461s CREATE FUNCTION 461s comment on function public.createEvent (p_cluster_name name, p_event_type text) is 461s 'FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) 461s 461s Create an sl_event entry'; 461s COMMENT 461s create or replace function public.createEvent (p_cluster_name name, p_event_type text, ev_data1 text) 461s returns bigint 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__createEvent' 461s language C 461s called on null input; 461s CREATE FUNCTION 461s comment on function public.createEvent (p_cluster_name name, p_event_type text, ev_data1 text) is 461s 'FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) 461s 461s Create an sl_event entry'; 461s COMMENT 461s create or replace function public.createEvent (p_cluster_name name, p_event_type text, ev_data1 text, ev_data2 text) 461s returns bigint 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__createEvent' 461s language C 461s called on null input; 461s CREATE FUNCTION 461s comment on function public.createEvent (p_cluster_name name, p_event_type text, ev_data1 text, ev_data2 text) is 461s 'FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) 461s 461s Create an sl_event entry'; 461s COMMENT 461s create or replace function public.createEvent (p_cluster_name name, p_event_type text, ev_data1 text, ev_data2 text, ev_data3 text) 461s returns bigint 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__createEvent' 461s language C 461s called on null input; 461s CREATE FUNCTION 461s comment on function public.createEvent (p_cluster_name name, p_event_type text, ev_data1 text, ev_data2 text, ev_data3 text) is 461s 'FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) 461s 461s Create an sl_event entry'; 461s COMMENT 461s create or replace function public.createEvent (p_cluster_name name, p_event_type text, ev_data1 text, ev_data2 text, ev_data3 text, ev_data4 text) 461s returns bigint 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__createEvent' 461s language C 461s called on null input; 461s CREATE FUNCTION 461s comment on function public.createEvent (p_cluster_name name, p_event_type text, ev_data1 text, ev_data2 text, ev_data3 text, ev_data4 text) is 461s 'FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) 461s 461s Create an sl_event entry'; 461s COMMENT 461s create or replace function public.createEvent (p_cluster_name name, p_event_type text, ev_data1 text, ev_data2 text, ev_data3 text, ev_data4 text, ev_data5 text) 461s returns bigint 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__createEvent' 461s language C 461s called on null input; 461s CREATE FUNCTION 461s comment on function public.createEvent (p_cluster_name name, p_event_type text, ev_data1 text, ev_data2 text, ev_data3 text, ev_data4 text, ev_data5 text) is 461s 'FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) 461s 461s Create an sl_event entry'; 461s COMMENT 461s create or replace function public.createEvent (p_cluster_name name, p_event_type text, ev_data1 text, ev_data2 text, ev_data3 text, ev_data4 text, ev_data5 text, ev_data6 text) 461s returns bigint 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__createEvent' 461s language C 461s called on null input; 461s CREATE FUNCTION 461s comment on function public.createEvent (p_cluster_name name, p_event_type text, ev_data1 text, ev_data2 text, ev_data3 text, ev_data4 text, ev_data5 text, ev_data6 text) is 461s 'FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) 461s 461s Create an sl_event entry'; 461s COMMENT 461s create or replace function public.createEvent (p_cluster_name name, p_event_type text, ev_data1 text, ev_data2 text, ev_data3 text, ev_data4 text, ev_data5 text, ev_data6 text, ev_data7 text) 461s returns bigint 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__createEvent' 461s language C 461s called on null input; 461s CREATE FUNCTION 461s comment on function public.createEvent (p_cluster_name name, p_event_type text, ev_data1 text, ev_data2 text, ev_data3 text, ev_data4 text, ev_data5 text, ev_data6 text, ev_data7 text) is 461s 'FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) 461s 461s Create an sl_event entry'; 461s COMMENT 461s create or replace function public.createEvent (p_cluster_name name, p_event_type text, ev_data1 text, ev_data2 text, ev_data3 text, ev_data4 text, ev_data5 text, ev_data6 text, ev_data7 text, ev_data8 text) 461s returns bigint 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__createEvent' 461s language C 461s called on null input; 461s CREATE FUNCTION 461s comment on function public.createEvent (p_cluster_name name, p_event_type text, ev_data1 text, ev_data2 text, ev_data3 text, ev_data4 text, ev_data5 text, ev_data6 text, ev_data7 text, ev_data8 text) is 461s 'FUNCTION createEvent (cluster_name, ev_type [, ev_data [...]]) 461s 461s Create an sl_event entry'; 461s COMMENT 461s create or replace function public.denyAccess () 461s returns trigger 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__denyAccess' 461s language C 461s security definer; 461s CREATE FUNCTION 461s comment on function public.denyAccess () is 461s 'Trigger function to prevent modifications to a table on a subscriber'; 461s COMMENT 461s grant execute on function public.denyAccess () to public; 461s GRANT 461s create or replace function public.lockedSet () 461s returns trigger 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__lockedSet' 461s language C; 461s CREATE FUNCTION 461s comment on function public.lockedSet () is 461s 'Trigger function to prevent modifications to a table before and after a moveSet()'; 461s COMMENT 461s create or replace function public.getLocalNodeId (p_cluster name) returns int4 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__getLocalNodeId' 461s language C 461s security definer; 461s CREATE FUNCTION 461s grant execute on function public.getLocalNodeId (p_cluster name) to public; 461s GRANT 461s comment on function public.getLocalNodeId (p_cluster name) is 461s 'Returns the node ID of the node being serviced on the local database'; 461s COMMENT 461s create or replace function public.getModuleVersion () returns text 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__getModuleVersion' 461s language C 461s security definer; 461s CREATE FUNCTION 461s grant execute on function public.getModuleVersion () to public; 461s GRANT 461s comment on function public.getModuleVersion () is 461s 'Returns the compiled-in version number of the Slony-I shared object'; 461s COMMENT 461s create or replace function public.resetSession() returns text 461s as '$libdir/slony1_funcs.2.2.11','_Slony_I_2_2_11__resetSession' 461s language C; 461s CREATE FUNCTION 461s create or replace function public.logApply () returns trigger 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__logApply' 461s language C 461s security definer; 461s CREATE FUNCTION 461s create or replace function public.logApplySetCacheSize (p_size int4) 461s returns int4 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__logApplySetCacheSize' 461s language C; 461s CREATE FUNCTION 461s create or replace function public.logApplySaveStats (p_cluster name, p_origin int4, p_duration interval) 461s returns int4 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__logApplySaveStats' 461s language C; 461s CREATE FUNCTION 461s create or replace function public.checkmoduleversion () returns text as $$ 461s declare 461s moduleversion text; 461s begin 461s select into moduleversion public.getModuleVersion(); 461s if moduleversion <> '2.2.11' then 461s raise exception 'Slonik version: 2.2.11 != Slony-I version in PG build %', 461s moduleversion; 461s end if; 461s return null; 461s end;$$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.checkmoduleversion () is 461s 'Inline test function that verifies that slonik request for STORE 461s NODE/INIT CLUSTER is being run against a conformant set of 461s schema/functions.'; 461s COMMENT 461s select public.checkmoduleversion(); 461s checkmoduleversion 461s -------------------- 461s 461s (1 row) 461s 461s create or replace function public.decode_tgargs(bytea) returns text[] as 461s '$libdir/slony1_funcs.2.2.11','_Slony_I_2_2_11__slon_decode_tgargs' language C security definer; 461s CREATE FUNCTION 461s comment on function public.decode_tgargs(bytea) is 461s 'Translates the contents of pg_trigger.tgargs to an array of text arguments'; 461s COMMENT 461s grant execute on function public.decode_tgargs(bytea) to public; 461s GRANT 461s create or replace function public.check_namespace_validity () returns boolean as $$ 461s declare 461s c_cluster text; 461s begin 461s c_cluster := 'main'; 461s if c_cluster !~ E'^[[:alpha:]_][[:alnum:]_\$]{0,62}$' then 461s raise exception 'Cluster name % is not a valid SQL symbol!', c_cluster; 461s else 461s raise notice 'checked validity of cluster % namespace - OK!', c_cluster; 461s end if; 461s return 't'; 461s end 461s $$ language plpgsql; 461s CREATE FUNCTION 461s select public.check_namespace_validity(); 461s check_namespace_validity 461s -------------------------- 461s t 461s (1 row) 461s 461s drop function public.check_namespace_validity(); 461s DROP FUNCTION 461s create or replace function public.logTrigger () returns trigger 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__logTrigger' 461s language C 461s security definer; 461s CREATE FUNCTION 461s comment on function public.logTrigger () is 461s 'This is the trigger that is executed on the origin node that causes 461s updates to be recorded in sl_log_1/sl_log_2.'; 461s COMMENT 461s grant execute on function public.logTrigger () to public; 461s GRANT 461s create or replace function public.terminateNodeConnections (p_failed_node int4) returns int4 461s as $$ 461s declare 461s v_row record; 461s begin 461s for v_row in select nl_nodeid, nl_conncnt, 461s nl_backendpid from public.sl_nodelock 461s where nl_nodeid = p_failed_node for update 461s loop 461s perform public.killBackend(v_row.nl_backendpid, 'TERM'); 461s delete from public.sl_nodelock 461s where nl_nodeid = v_row.nl_nodeid 461s and nl_conncnt = v_row.nl_conncnt; 461s end loop; 461s 461s return 0; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.terminateNodeConnections (p_failed_node int4) is 461s 'terminates all backends that have registered to be from the given node'; 461s COMMENT 461s create or replace function public.killBackend (p_pid int4, p_signame text) returns int4 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__killBackend' 461s language C; 461s CREATE FUNCTION 461s comment on function public.killBackend(p_pid int4, p_signame text) is 461s 'Send a signal to a postgres process. Requires superuser rights'; 461s COMMENT 461s create or replace function public.seqtrack (p_seqid int4, p_seqval int8) returns int8 461s as '$libdir/slony1_funcs.2.2.11', '_Slony_I_2_2_11__seqtrack' 461s strict language C; 461s CREATE FUNCTION 461s comment on function public.seqtrack(p_seqid int4, p_seqval int8) is 461s 'Returns NULL if seqval has not changed since the last call for seqid'; 461s COMMENT 461s create or replace function public.slon_quote_brute(p_tab_fqname text) returns text 461s as $$ 461s declare 461s v_fqname text default ''; 461s begin 461s v_fqname := '"' || replace(p_tab_fqname,'"','""') || '"'; 461s return v_fqname; 461s end; 461s $$ language plpgsql immutable; 461s CREATE FUNCTION 461s comment on function public.slon_quote_brute(p_tab_fqname text) is 461s 'Brutally quote the given text'; 461s COMMENT 461s create or replace function public.slon_quote_input(p_tab_fqname text) returns text as $$ 461s declare 461s v_nsp_name text; 461s v_tab_name text; 461s v_i integer; 461s v_l integer; 461s v_pq2 integer; 461s begin 461s v_l := length(p_tab_fqname); 461s 461s -- Let us search for the dot 461s if p_tab_fqname like '"%' then 461s -- if the first part of the ident starts with a double quote, search 461s -- for the closing double quote, skipping over double double quotes. 461s v_i := 2; 461s while v_i <= v_l loop 461s if substr(p_tab_fqname, v_i, 1) != '"' then 461s v_i := v_i + 1; 461s else 461s v_i := v_i + 1; 461s if substr(p_tab_fqname, v_i, 1) != '"' then 461s exit; 461s end if; 461s v_i := v_i + 1; 461s end if; 461s end loop; 461s else 461s -- first part of ident is not quoted, search for the dot directly 461s v_i := 1; 461s while v_i <= v_l loop 461s if substr(p_tab_fqname, v_i, 1) = '.' then 461s exit; 461s end if; 461s v_i := v_i + 1; 461s end loop; 461s end if; 461s 461s -- v_i now points at the dot or behind the string. 461s 461s if substr(p_tab_fqname, v_i, 1) = '.' then 461s -- There is a dot now, so split the ident into its namespace 461s -- and objname parts and make sure each is quoted 461s v_nsp_name := substr(p_tab_fqname, 1, v_i - 1); 461s v_tab_name := substr(p_tab_fqname, v_i + 1); 461s if v_nsp_name not like '"%' then 461s v_nsp_name := '"' || replace(v_nsp_name, '"', '""') || 461s '"'; 461s end if; 461s if v_tab_name not like '"%' then 461s v_tab_name := '"' || replace(v_tab_name, '"', '""') || 461s '"'; 461s end if; 461s 461s return v_nsp_name || '.' || v_tab_name; 461s else 461s -- No dot ... must be just an ident without schema 461s if p_tab_fqname like '"%' then 461s return p_tab_fqname; 461s else 461s return '"' || replace(p_tab_fqname, '"', '""') || '"'; 461s end if; 461s end if; 461s 461s end;$$ language plpgsql immutable; 461s CREATE FUNCTION 461s comment on function public.slon_quote_input(p_text text) is 461s 'quote all words that aren''t quoted yet'; 461s COMMENT 461s create or replace function public.slonyVersionMajor() 461s returns int4 461s as $$ 461s begin 461s return 2; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.slonyVersionMajor () is 461s 'Returns the major version number of the slony schema'; 461s COMMENT 461s create or replace function public.slonyVersionMinor() 461s returns int4 461s as $$ 461s begin 461s return 2; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.slonyVersionMinor () is 461s 'Returns the minor version number of the slony schema'; 461s COMMENT 461s create or replace function public.slonyVersionPatchlevel() 461s returns int4 461s as $$ 461s begin 461s return 11; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.slonyVersionPatchlevel () is 461s 'Returns the version patch level of the slony schema'; 461s COMMENT 461s create or replace function public.slonyVersion() 461s returns text 461s as $$ 461s begin 461s return public.slonyVersionMajor()::text || '.' || 461s public.slonyVersionMinor()::text || '.' || 461s public.slonyVersionPatchlevel()::text ; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.slonyVersion() is 461s 'Returns the version number of the slony schema'; 461s COMMENT 461s create or replace function public.registry_set_int4(p_key text, p_value int4) 461s returns int4 as $$ 461s BEGIN 461s if p_value is null then 461s delete from public.sl_registry 461s where reg_key = p_key; 461s else 461s lock table public.sl_registry; 461s update public.sl_registry 461s set reg_int4 = p_value 461s where reg_key = p_key; 461s if not found then 461s insert into public.sl_registry (reg_key, reg_int4) 461s values (p_key, p_value); 461s end if; 461s end if; 461s return p_value; 461s END; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.registry_set_int4(p_key text, p_value int4) is 461s 'registry_set_int4(key, value) 461s 461s Set or delete a registry value'; 461s COMMENT 461s create or replace function public.registry_get_int4(p_key text, p_default int4) 461s returns int4 as $$ 461s DECLARE 461s v_value int4; 461s BEGIN 461s select reg_int4 into v_value from public.sl_registry 461s where reg_key = p_key; 461s if not found then 461s v_value = p_default; 461s if p_default notnull then 461s perform public.registry_set_int4(p_key, p_default); 461s end if; 461s else 461s if v_value is null then 461s raise exception 'Slony-I: registry key % is not an int4 value', 461s p_key; 461s end if; 461s end if; 461s return v_value; 461s END; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.registry_get_int4(p_key text, p_default int4) is 461s 'registry_get_int4(key, value) 461s 461s Get a registry value. If not present, set and return the default.'; 461s COMMENT 461s create or replace function public.registry_set_text(p_key text, p_value text) 461s returns text as $$ 461s BEGIN 461s if p_value is null then 461s delete from public.sl_registry 461s where reg_key = p_key; 461s else 461s lock table public.sl_registry; 461s update public.sl_registry 461s set reg_text = p_value 461s where reg_key = p_key; 461s if not found then 461s insert into public.sl_registry (reg_key, reg_text) 461s values (p_key, p_value); 461s end if; 461s end if; 461s return p_value; 461s END; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.registry_set_text(text, text) is 461s 'registry_set_text(key, value) 461s 461s Set or delete a registry value'; 461s COMMENT 461s create or replace function public.registry_get_text(p_key text, p_default text) 461s returns text as $$ 461s DECLARE 461s v_value text; 461s BEGIN 461s select reg_text into v_value from public.sl_registry 461s where reg_key = p_key; 461s if not found then 461s v_value = p_default; 461s if p_default notnull then 461s perform public.registry_set_text(p_key, p_default); 461s end if; 461s else 461s if v_value is null then 461s raise exception 'Slony-I: registry key % is not a text value', 461s p_key; 461s end if; 461s end if; 461s return v_value; 461s END; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.registry_get_text(p_key text, p_default text) is 461s 'registry_get_text(key, value) 461s 461s Get a registry value. If not present, set and return the default.'; 461s COMMENT 461s create or replace function public.registry_set_timestamp(p_key text, p_value timestamptz) 461s returns timestamp as $$ 461s BEGIN 461s if p_value is null then 461s delete from public.sl_registry 461s where reg_key = p_key; 461s else 461s lock table public.sl_registry; 461s update public.sl_registry 461s set reg_timestamp = p_value 461s where reg_key = p_key; 461s if not found then 461s insert into public.sl_registry (reg_key, reg_timestamp) 461s values (p_key, p_value); 461s end if; 461s end if; 461s return p_value; 461s END; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.registry_set_timestamp(p_key text, p_value timestamptz) is 461s 'registry_set_timestamp(key, value) 461s 461s Set or delete a registry value'; 461s COMMENT 461s create or replace function public.registry_get_timestamp(p_key text, p_default timestamptz) 461s returns timestamp as $$ 461s DECLARE 461s v_value timestamp; 461s BEGIN 461s select reg_timestamp into v_value from public.sl_registry 461s where reg_key = p_key; 461s if not found then 461s v_value = p_default; 461s if p_default notnull then 461s perform public.registry_set_timestamp(p_key, p_default); 461s end if; 461s else 461s if v_value is null then 461s raise exception 'Slony-I: registry key % is not an timestamp value', 461s p_key; 461s end if; 461s end if; 461s return v_value; 461s END; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.registry_get_timestamp(p_key text, p_default timestamptz) is 461s 'registry_get_timestamp(key, value) 461s 461s Get a registry value. If not present, set and return the default.'; 461s COMMENT 461s create or replace function public.cleanupNodelock () 461s returns int4 461s as $$ 461s declare 461s v_row record; 461s begin 461s for v_row in select nl_nodeid, nl_conncnt, nl_backendpid 461s from public.sl_nodelock 461s for update 461s loop 461s if public.killBackend(v_row.nl_backendpid, 'NULL') < 0 then 461s raise notice 'Slony-I: cleanup stale sl_nodelock entry for pid=%', 461s v_row.nl_backendpid; 461s delete from public.sl_nodelock where 461s nl_nodeid = v_row.nl_nodeid and 461s nl_conncnt = v_row.nl_conncnt; 461s end if; 461s end loop; 461s 461s return 0; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.cleanupNodelock() is 461s 'Clean up stale entries when restarting slon'; 461s COMMENT 461s create or replace function public.registerNodeConnection (p_nodeid int4) 461s returns int4 461s as $$ 461s begin 461s insert into public.sl_nodelock 461s (nl_nodeid, nl_backendpid) 461s values 461s (p_nodeid, pg_backend_pid()); 461s 461s return 0; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.registerNodeConnection (p_nodeid int4) is 461s 'Register (uniquely) the node connection so that only one slon can service the node'; 461s COMMENT 461s create or replace function public.initializeLocalNode (p_local_node_id int4, p_comment text) 461s returns int4 461s as $$ 461s declare 461s v_old_node_id int4; 461s v_first_log_no int4; 461s v_event_seq int8; 461s begin 461s -- ---- 461s -- Make sure this node is uninitialized or got reset 461s -- ---- 461s select last_value::int4 into v_old_node_id from public.sl_local_node_id; 461s if v_old_node_id != -1 then 461s raise exception 'Slony-I: This node is already initialized'; 461s end if; 461s 461s -- ---- 461s -- Set sl_local_node_id to the requested value and add our 461s -- own system to sl_node. 461s -- ---- 461s perform setval('public.sl_local_node_id', p_local_node_id); 461s perform public.storeNode_int (p_local_node_id, p_comment); 461s 461s if (pg_catalog.current_setting('max_identifier_length')::integer - pg_catalog.length('public')) < 5 then 461s raise notice 'Slony-I: Cluster name length [%] versus system max_identifier_length [%] ', pg_catalog.length('public'), pg_catalog.current_setting('max_identifier_length'); 461s raise notice 'leaves narrow/no room for some Slony-I-generated objects (such as indexes).'; 461s raise notice 'You may run into problems later!'; 461s end if; 461s 461s -- 461s -- Put the apply trigger onto sl_log_1 and sl_log_2 461s -- 461s create trigger apply_trigger 461s before INSERT on public.sl_log_1 461s for each row execute procedure public.logApply('_main'); 461s alter table public.sl_log_1 461s enable replica trigger apply_trigger; 461s create trigger apply_trigger 461s before INSERT on public.sl_log_2 461s for each row execute procedure public.logApply('_main'); 461s alter table public.sl_log_2 461s enable replica trigger apply_trigger; 461s 461s return p_local_node_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.initializeLocalNode (p_local_node_id int4, p_comment text) is 461s 'no_id - Node ID # 461s no_comment - Human-oriented comment 461s 461s Initializes the new node, no_id'; 461s COMMENT 461s create or replace function public.storeNode (p_no_id int4, p_no_comment text) 461s returns bigint 461s as $$ 461s begin 461s perform public.storeNode_int (p_no_id, p_no_comment); 461s return public.createEvent('_main', 'STORE_NODE', 461s p_no_id::text, p_no_comment::text); 461s end; 461s $$ language plpgsql 461s called on null input; 461s CREATE FUNCTION 461s comment on function public.storeNode(p_no_id int4, p_no_comment text) is 461s 'no_id - Node ID # 461s no_comment - Human-oriented comment 461s 461s Generate the STORE_NODE event for node no_id'; 461s COMMENT 461s create or replace function public.storeNode_int (p_no_id int4, p_no_comment text) 461s returns int4 461s as $$ 461s declare 461s v_old_row record; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Check if the node exists 461s -- ---- 461s select * into v_old_row 461s from public.sl_node 461s where no_id = p_no_id 461s for update; 461s if found then 461s -- ---- 461s -- Node exists, update the existing row. 461s -- ---- 461s update public.sl_node 461s set no_comment = p_no_comment 461s where no_id = p_no_id; 461s else 461s -- ---- 461s -- New node, insert the sl_node row 461s -- ---- 461s insert into public.sl_node 461s (no_id, no_active, no_comment,no_failed) values 461s (p_no_id, 'f', p_no_comment,false); 461s end if; 461s 461s return p_no_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.storeNode_int(p_no_id int4, p_no_comment text) is 461s 'no_id - Node ID # 461s no_comment - Human-oriented comment 461s 461s Internal function to process the STORE_NODE event for node no_id'; 461s COMMENT 461s create or replace function public.enableNode (p_no_id int4) 461s returns bigint 461s as $$ 461s declare 461s v_local_node_id int4; 461s v_node_row record; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Check that we are the node to activate and that we are 461s -- currently disabled. 461s -- ---- 461s v_local_node_id := public.getLocalNodeId('_main'); 461s select * into v_node_row 461s from public.sl_node 461s where no_id = p_no_id 461s for update; 461s if not found then 461s raise exception 'Slony-I: node % not found', p_no_id; 461s end if; 461s if v_node_row.no_active then 461s raise exception 'Slony-I: node % is already active', p_no_id; 461s end if; 461s 461s -- ---- 461s -- Activate this node and generate the ENABLE_NODE event 461s -- ---- 461s perform public.enableNode_int (p_no_id); 461s return public.createEvent('_main', 'ENABLE_NODE', 461s p_no_id::text); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.enableNode(p_no_id int4) is 461s 'no_id - Node ID # 461s 461s Generate the ENABLE_NODE event for node no_id'; 461s COMMENT 461s create or replace function public.enableNode_int (p_no_id int4) 461s returns int4 461s as $$ 461s declare 461s v_local_node_id int4; 461s v_node_row record; 461s v_sub_row record; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Check that the node is inactive 461s -- ---- 461s select * into v_node_row 461s from public.sl_node 461s where no_id = p_no_id 461s for update; 461s if not found then 461s raise exception 'Slony-I: node % not found', p_no_id; 461s end if; 461s if v_node_row.no_active then 461s return p_no_id; 461s end if; 461s 461s -- ---- 461s -- Activate the node and generate sl_confirm status rows for it. 461s -- ---- 461s update public.sl_node 461s set no_active = 't' 461s where no_id = p_no_id; 461s insert into public.sl_confirm 461s (con_origin, con_received, con_seqno) 461s select no_id, p_no_id, 0 from public.sl_node 461s where no_id != p_no_id 461s and no_active; 461s insert into public.sl_confirm 461s (con_origin, con_received, con_seqno) 461s select p_no_id, no_id, 0 from public.sl_node 461s where no_id != p_no_id 461s and no_active; 461s 461s -- ---- 461s -- Generate ENABLE_SUBSCRIPTION events for all sets that 461s -- origin here and are subscribed by the just enabled node. 461s -- ---- 461s v_local_node_id := public.getLocalNodeId('_main'); 461s for v_sub_row in select SUB.sub_set, SUB.sub_provider from 461s public.sl_set S, 461s public.sl_subscribe SUB 461s where S.set_origin = v_local_node_id 461s and S.set_id = SUB.sub_set 461s and SUB.sub_receiver = p_no_id 461s for update of S 461s loop 461s perform public.enableSubscription (v_sub_row.sub_set, 461s v_sub_row.sub_provider, p_no_id); 461s end loop; 461s 461s return p_no_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.enableNode_int(p_no_id int4) is 461s 'no_id - Node ID # 461s 461s Internal function to process the ENABLE_NODE event for node no_id'; 461s COMMENT 461s create or replace function public.disableNode (p_no_id int4) 461s returns bigint 461s as $$ 461s begin 461s -- **** TODO **** 461s raise exception 'Slony-I: disableNode() not implemented'; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.disableNode(p_no_id int4) is 461s 'generate DISABLE_NODE event for node no_id'; 461s COMMENT 461s create or replace function public.disableNode_int (p_no_id int4) 461s returns int4 461s as $$ 461s begin 461s -- **** TODO **** 461s raise exception 'Slony-I: disableNode_int() not implemented'; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.disableNode(p_no_id int4) is 461s 'process DISABLE_NODE event for node no_id 461s 461s NOTE: This is not yet implemented!'; 461s COMMENT 461s create or replace function public.dropNode (p_no_ids int4[]) 461s returns bigint 461s as $$ 461s declare 461s v_node_row record; 461s v_idx integer; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Check that this got called on a different node 461s -- ---- 461s if public.getLocalNodeId('_main') = ANY (p_no_ids) then 461s raise exception 'Slony-I: DROP_NODE cannot initiate on the dropped node'; 461s end if; 461s 461s -- 461s -- if any of the deleted nodes are receivers we drop the sl_subscribe line 461s -- 461s delete from public.sl_subscribe where sub_receiver = ANY (p_no_ids); 461s 461s v_idx:=1; 461s LOOP 461s EXIT WHEN v_idx>array_upper(p_no_ids,1) ; 461s select * into v_node_row from public.sl_node 461s where no_id = p_no_ids[v_idx] 461s for update; 461s if not found then 461s raise exception 'Slony-I: unknown node ID % %', p_no_ids[v_idx],v_idx; 461s end if; 461s -- ---- 461s -- Make sure we do not break other nodes subscriptions with this 461s -- ---- 461s if exists (select true from public.sl_subscribe 461s where sub_provider = p_no_ids[v_idx]) 461s then 461s raise exception 'Slony-I: Node % is still configured as a data provider', 461s p_no_ids[v_idx]; 461s end if; 461s 461s -- ---- 461s -- Make sure no set originates there any more 461s -- ---- 461s if exists (select true from public.sl_set 461s where set_origin = p_no_ids[v_idx]) 461s then 461s raise exception 'Slony-I: Node % is still origin of one or more sets', 461s p_no_ids[v_idx]; 461s end if; 461s 461s -- ---- 461s -- Call the internal drop functionality and generate the event 461s -- ---- 461s perform public.dropNode_int(p_no_ids[v_idx]); 461s v_idx:=v_idx+1; 461s END LOOP; 461s return public.createEvent('_main', 'DROP_NODE', 461s array_to_string(p_no_ids,',')); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.dropNode(p_no_ids int4[]) is 461s 'generate DROP_NODE event to drop node node_id from replication'; 461s COMMENT 461s create or replace function public.dropNode_int (p_no_id int4) 461s returns int4 461s as $$ 461s declare 461s v_tab_row record; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- If the dropped node is a remote node, clean the configuration 461s -- from all traces for it. 461s -- ---- 461s if p_no_id <> public.getLocalNodeId('_main') then 461s delete from public.sl_subscribe 461s where sub_receiver = p_no_id; 461s delete from public.sl_listen 461s where li_origin = p_no_id 461s or li_provider = p_no_id 461s or li_receiver = p_no_id; 461s delete from public.sl_path 461s where pa_server = p_no_id 461s or pa_client = p_no_id; 461s delete from public.sl_confirm 461s where con_origin = p_no_id 461s or con_received = p_no_id; 461s delete from public.sl_event 461s where ev_origin = p_no_id; 461s delete from public.sl_node 461s where no_id = p_no_id; 461s 461s return p_no_id; 461s end if; 461s 461s -- ---- 461s -- This is us ... deactivate the node for now, the daemon 461s -- will call uninstallNode() in a separate transaction. 461s -- ---- 461s update public.sl_node 461s set no_active = false 461s where no_id = p_no_id; 461s 461s -- Rewrite sl_listen table 461s perform public.RebuildListenEntries(); 461s 461s return p_no_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.dropNode_int(p_no_id int4) is 461s 'internal function to process DROP_NODE event to drop node node_id from replication'; 461s COMMENT 461s create or replace function public.preFailover(p_failed_node int4,p_is_candidate boolean) 461s returns int4 461s as $$ 461s declare 461s v_row record; 461s v_row2 record; 461s v_n int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- All consistency checks first 461s 461s if p_is_candidate then 461s -- ---- 461s -- Check all sets originating on the failed node 461s -- ---- 461s for v_row in select set_id 461s from public.sl_set 461s where set_origin = p_failed_node 461s loop 461s -- ---- 461s -- Check that the backup node is subscribed to all sets 461s -- that originate on the failed node 461s -- ---- 461s select into v_row2 sub_forward, sub_active 461s from public.sl_subscribe 461s where sub_set = v_row.set_id 461s and sub_receiver = public.getLocalNodeId('_main'); 461s if not found then 461s raise exception 'Slony-I: cannot failover - node % is not subscribed to set %', 461s public.getLocalNodeId('_main'), v_row.set_id; 461s end if; 461s 461s -- ---- 461s -- Check that the subscription is active 461s -- ---- 461s if not v_row2.sub_active then 461s raise exception 'Slony-I: cannot failover - subscription for set % is not active', 461s v_row.set_id; 461s end if; 461s 461s -- ---- 461s -- If there are other subscribers, the backup node needs to 461s -- be a forwarder too. 461s -- ---- 461s select into v_n count(*) 461s from public.sl_subscribe 461s where sub_set = v_row.set_id 461s and sub_receiver <> public.getLocalNodeId('_main'); 461s if v_n > 0 and not v_row2.sub_forward then 461s raise exception 'Slony-I: cannot failover - node % is not a forwarder of set %', 461s public.getLocalNodeId('_main'), v_row.set_id; 461s end if; 461s end loop; 461s end if; 461s 461s -- ---- 461s -- Terminate all connections of the failed node the hard way 461s -- ---- 461s perform public.terminateNodeConnections(p_failed_node); 461s 461s update public.sl_path set pa_conninfo='' WHERE 461s pa_server=p_failed_node; 461s notify "_main_Restart"; 461s -- ---- 461s -- That is it - so far. 461s -- ---- 461s return p_failed_node; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.preFailover(p_failed_node int4,is_failover_candidate boolean) is 461s 'Prepare for a failover. This function is called on all candidate nodes. 461s It blanks the paths to the failed node 461s and then restart of all node daemons.'; 461s COMMENT 461s create or replace function public.failedNode(p_failed_node int4, p_backup_node int4,p_failed_nodes integer[]) 461s returns int4 461s as $$ 461s declare 461s v_row record; 461s v_row2 record; 461s v_failed boolean; 461s v_restart_required boolean; 461s begin 461s 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s v_restart_required:=false; 461s -- 461s -- any nodes other than the backup receiving 461s -- ANY subscription from a failed node 461s -- will now get that data from the backup node. 461s update public.sl_subscribe set 461s sub_provider=p_backup_node 461s where sub_provider=p_failed_node 461s and sub_receiver<>p_backup_node 461s and sub_receiver <> ALL (p_failed_nodes); 461s if found then 461s v_restart_required:=true; 461s end if; 461s -- 461s -- if this node is receiving a subscription from the backup node 461s -- with a failed node as the provider we need to fix this. 461s update public.sl_subscribe set 461s sub_provider=p_backup_node 461s from public.sl_set 461s where set_id = sub_set 461s and set_origin=p_failed_node 461s and sub_provider = ANY(p_failed_nodes) 461s and sub_receiver=public.getLocalNodeId('_main'); 461s 461s -- ---- 461s -- Terminate all connections of the failed node the hard way 461s -- ---- 461s perform public.terminateNodeConnections(p_failed_node); 461s 461s -- Clear out the paths for the failed node. 461s -- This ensures that *this* node won't be pulling data from 461s -- the failed node even if it *does* become accessible 461s 461s update public.sl_path set pa_conninfo='' WHERE 461s pa_server=p_failed_node 461s and pa_conninfo<>''; 461s 461s if found then 461s v_restart_required:=true; 461s end if; 461s 461s v_failed := exists (select 1 from public.sl_node 461s where no_failed=true and no_id=p_failed_node); 461s 461s if not v_failed then 461s 461s update public.sl_node set no_failed=true where no_id = ANY (p_failed_nodes) 461s and no_failed=false; 461s if found then 461s v_restart_required:=true; 461s end if; 461s end if; 461s 461s if v_restart_required then 461s -- Rewrite sl_listen table 461s perform public.RebuildListenEntries(); 461s 461s -- ---- 461s -- Make sure the node daemon will restart 461s -- ---- 461s notify "_main_Restart"; 461s end if; 461s 461s 461s -- ---- 461s -- That is it - so far. 461s -- ---- 461s return p_failed_node; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.failedNode(p_failed_node int4, p_backup_node int4,p_failed_nodes integer[]) is 461s 'Initiate failover from failed_node to backup_node. This function must be called on all nodes, 461s and then waited for the restart of all node daemons.'; 461s COMMENT 461s create or replace function public.failedNode2 (p_failed_node int4, p_backup_node int4, p_ev_seqno int8, p_failed_nodes integer[]) 461s returns bigint 461s as $$ 461s declare 461s v_row record; 461s v_new_event bigint; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s select * into v_row 461s from public.sl_event 461s where ev_origin = p_failed_node 461s and ev_seqno = p_ev_seqno; 461s if not found then 461s raise exception 'Slony-I: event %,% not found', 461s p_failed_node, p_ev_seqno; 461s end if; 461s 461s update public.sl_node set no_failed=true where no_id = ANY 461s (p_failed_nodes) and no_failed=false; 461s -- Rewrite sl_listen table 461s perform public.RebuildListenEntries(); 461s -- ---- 461s -- Make sure the node daemon will restart 461s -- ---- 461s raise notice 'calling restart node %',p_failed_node; 461s 461s notify "_main_Restart"; 461s 461s select public.createEvent('_main','FAILOVER_NODE', 461s p_failed_node::text,p_ev_seqno::text, 461s array_to_string(p_failed_nodes,',')) 461s into v_new_event; 461s 461s 461s return v_new_event; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.failedNode2 (p_failed_node int4, p_backup_node int4, p_ev_seqno int8,p_failed_nodes integer[] ) is 461s 'FUNCTION failedNode2 (failed_node, backup_node, set_id, ev_seqno, ev_seqfake,p_failed_nodes) 461s 461s On the node that has the highest sequence number of the failed node, 461s fake the FAILOVER_SET event.'; 461s COMMENT 461s create or replace function public.failedNode3 (p_failed_node int4, p_backup_node int4,p_seq_no bigint) 461s returns int4 461s as $$ 461s declare 461s 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s perform public.failoverSet_int(p_failed_node, 461s p_backup_node,p_seq_no); 461s 461s notify "_main_Restart"; 461s return 0; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s NOTICE: function public.clonenodeprepare(int4,int4,text) does not exist, skipping 461s create or replace function public.failoverSet_int (p_failed_node int4, p_backup_node int4,p_last_seqno bigint) 461s returns int4 461s as $$ 461s declare 461s v_row record; 461s v_last_sync int8; 461s v_set int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s SELECT max(ev_seqno) into v_last_sync FROM public.sl_event where 461s ev_origin=p_failed_node; 461s if v_last_sync > p_last_seqno then 461s -- this node is ahead of the last sequence number from the 461s -- failed node that the backup node has. 461s -- this node must unsubscribe from all sets from the origin. 461s for v_set in select set_id from public.sl_set where 461s set_origin=p_failed_node 461s loop 461s raise warning 'Slony is dropping the subscription of set % found sync %s bigger than %s ' 461s , v_set, v_last_sync::text, p_last_seqno::text; 461s perform public.unsubscribeSet(v_set, 461s public.getLocalNodeId('_main'), 461s true); 461s end loop; 461s delete from public.sl_event where ev_origin=p_failed_node 461s and ev_seqno > p_last_seqno; 461s end if; 461s -- ---- 461s -- Change the origin of the set now to the backup node. 461s -- On the backup node this includes changing all the 461s -- trigger and protection stuff 461s for v_set in select set_id from public.sl_set where 461s set_origin=p_failed_node 461s loop 461s -- ---- 461s if p_backup_node = public.getLocalNodeId('_main') then 461s delete from public.sl_setsync 461s where ssy_setid = v_set; 461s delete from public.sl_subscribe 461s where sub_set = v_set 461s and sub_receiver = p_backup_node; 461s update public.sl_set 461s set set_origin = p_backup_node 461s where set_id = v_set; 461s update public.sl_subscribe 461s set sub_provider=p_backup_node 461s FROM public.sl_node receive_node 461s where sub_set = v_set 461s and sub_provider=p_failed_node 461s and sub_receiver=receive_node.no_id 461s and receive_node.no_failed=false; 461s 461s for v_row in select * from public.sl_table 461s where tab_set = v_set 461s order by tab_id 461s loop 461s perform public.alterTableConfigureTriggers(v_row.tab_id); 461s end loop; 461s else 461s raise notice 'deleting from sl_subscribe all rows with receiver %', 461s p_backup_node; 461s 461s delete from public.sl_subscribe 461s where sub_set = v_set 461s and sub_receiver = p_backup_node; 461s 461s update public.sl_subscribe 461s set sub_provider=p_backup_node 461s FROM public.sl_node receive_node 461s where sub_set = v_set 461s and sub_provider=p_failed_node 461s and sub_provider=p_failed_node 461s and sub_receiver=receive_node.no_id 461s and receive_node.no_failed=false; 461s update public.sl_set 461s set set_origin = p_backup_node 461s where set_id = v_set; 461s -- ---- 461s -- If we are a subscriber of the set ourself, change our 461s -- setsync status to reflect the new set origin. 461s -- ---- 461s if exists (select true from public.sl_subscribe 461s where sub_set = v_set 461s and sub_receiver = public.getLocalNodeId( 461s '_main')) 461s then 461s delete from public.sl_setsync 461s where ssy_setid = v_set; 461s 461s select coalesce(max(ev_seqno), 0) into v_last_sync 461s from public.sl_event 461s where ev_origin = p_backup_node 461s and ev_type = 'SYNC'; 461s if v_last_sync > 0 then 461s insert into public.sl_setsync 461s (ssy_setid, ssy_origin, ssy_seqno, 461s ssy_snapshot, ssy_action_list) 461s select v_set, p_backup_node, v_last_sync, 461s ev_snapshot, NULL 461s from public.sl_event 461s where ev_origin = p_backup_node 461s and ev_seqno = v_last_sync; 461s else 461s insert into public.sl_setsync 461s (ssy_setid, ssy_origin, ssy_seqno, 461s ssy_snapshot, ssy_action_list) 461s values (v_set, p_backup_node, '0', 461s '1:1:', NULL); 461s end if; 461s end if; 461s end if; 461s end loop; 461s 461s --If there are any subscriptions with 461s --the failed_node being the provider then 461s --we want to redirect those subscriptions 461s --to come from the backup node. 461s -- 461s -- The backup node should be a valid 461s -- provider for all subscriptions served 461s -- by the failed node. (otherwise it 461s -- wouldn't be a allowable backup node). 461s -- delete from public.sl_subscribe 461s -- where sub_receiver=p_backup_node; 461s 461s update public.sl_subscribe 461s set sub_provider=p_backup_node 461s from public.sl_node 461s where sub_provider=p_failed_node 461s and sl_node.no_id=sub_receiver 461s and sl_node.no_failed=false 461s and sub_receiver<>p_backup_node; 461s 461s update public.sl_subscribe 461s set sub_provider=(select set_origin from 461s public.sl_set where set_id= 461s sub_set) 461s where sub_provider=p_failed_node 461s and sub_receiver=p_backup_node; 461s 461s update public.sl_node 461s set no_active=false WHERE 461s no_id=p_failed_node; 461s 461s -- Rewrite sl_listen table 461s perform public.RebuildListenEntries(); 461s 461s 461s return p_failed_node; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.failoverSet_int (p_failed_node int4, p_backup_node int4,p_seqno bigint) is 461s 'FUNCTION failoverSet_int (failed_node, backup_node, set_id, wait_seqno) 461s 461s Finish failover for one set.'; 461s COMMENT 461s create or replace function public.uninstallNode () 461s returns int4 461s as $$ 461s declare 461s v_tab_row record; 461s begin 461s raise notice 'Slony-I: Please drop schema "_main"'; 461s return 0; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.uninstallNode() is 461s 'Reset the whole database to standalone by removing the whole 461s replication system.'; 461s COMMENT 461s DROP FUNCTION IF EXISTS public.cloneNodePrepare(int4,int4,text); 461s DROP FUNCTION 461s create or replace function public.cloneNodePrepare (p_no_id int4, p_no_provider int4, p_no_comment text) 461s returns bigint 461s as $$ 461s begin 461s perform public.cloneNodePrepare_int (p_no_id, p_no_provider, p_no_comment); 461s return public.createEvent('_main', 'CLONE_NODE', 461s p_no_id::text, p_no_provider::text, 461s p_no_comment::text); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.cloneNodePrepare(p_no_id int4, p_no_provider int4, p_no_comment text) is 461s 'Prepare for cloning a node.'; 461s COMMENT 461s create or replace function public.cloneNodePrepare_int (p_no_id int4, p_no_provider int4, p_no_comment text) 461s returns int4 461s as $$ 461s declare 461s v_dummy int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s update public.sl_node set 461s no_active = np.no_active, 461s no_comment = np.no_comment, 461s no_failed = np.no_failed 461s from public.sl_node np 461s where np.no_id = p_no_provider 461s and sl_node.no_id = p_no_id; 461s if not found then 461s insert into public.sl_node 461s (no_id, no_active, no_comment,no_failed) 461s select p_no_id, no_active, p_no_comment, no_failed 461s from public.sl_node 461s where no_id = p_no_provider; 461s end if; 461s 461s insert into public.sl_path 461s (pa_server, pa_client, pa_conninfo, pa_connretry) 461s select pa_server, p_no_id, '', pa_connretry 461s from public.sl_path 461s where pa_client = p_no_provider 461s and (pa_server, p_no_id) not in (select pa_server, pa_client 461s from public.sl_path); 461s 461s insert into public.sl_path 461s (pa_server, pa_client, pa_conninfo, pa_connretry) 461s select p_no_id, pa_client, '', pa_connretry 461s from public.sl_path 461s where pa_server = p_no_provider 461s and (p_no_id, pa_client) not in (select pa_server, pa_client 461s from public.sl_path); 461s 461s insert into public.sl_subscribe 461s (sub_set, sub_provider, sub_receiver, sub_forward, sub_active) 461s select sub_set, sub_provider, p_no_id, sub_forward, sub_active 461s from public.sl_subscribe 461s where sub_receiver = p_no_provider; 461s 461s insert into public.sl_confirm 461s (con_origin, con_received, con_seqno, con_timestamp) 461s select con_origin, p_no_id, con_seqno, con_timestamp 461s from public.sl_confirm 461s where con_received = p_no_provider; 461s 461s perform public.RebuildListenEntries(); 461s 461s return 0; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.cloneNodePrepare_int(p_no_id int4, p_no_provider int4, p_no_comment text) is 461s 'Internal part of cloneNodePrepare().'; 461s COMMENT 461s create or replace function public.cloneNodeFinish (p_no_id int4, p_no_provider int4) 461s returns int4 461s as $$ 461s declare 461s v_row record; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s perform "pg_catalog".setval('public.sl_local_node_id', p_no_id); 461s perform public.resetSession(); 461s for v_row in select sub_set from public.sl_subscribe 461s where sub_receiver = p_no_id 461s loop 461s perform public.updateReloid(v_row.sub_set, p_no_id); 461s end loop; 461s 461s perform public.RebuildListenEntries(); 461s 461s delete from public.sl_confirm 461s where con_received = p_no_id; 461s insert into public.sl_confirm 461s (con_origin, con_received, con_seqno, con_timestamp) 461s select con_origin, p_no_id, con_seqno, con_timestamp 461s from public.sl_confirm 461s where con_received = p_no_provider; 461s insert into public.sl_confirm 461s (con_origin, con_received, con_seqno, con_timestamp) 461s select p_no_provider, p_no_id, 461s (select max(ev_seqno) from public.sl_event 461s where ev_origin = p_no_provider), current_timestamp; 461s 461s return 0; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.cloneNodeFinish(p_no_id int4, p_no_provider int4) is 461s 'Internal part of cloneNodePrepare().'; 461s COMMENT 461s create or replace function public.storePath (p_pa_server int4, p_pa_client int4, p_pa_conninfo text, p_pa_connretry int4) 461s returns bigint 461s as $$ 461s begin 461s perform public.storePath_int(p_pa_server, p_pa_client, 461s p_pa_conninfo, p_pa_connretry); 461s return public.createEvent('_main', 'STORE_PATH', 461s p_pa_server::text, p_pa_client::text, 461s p_pa_conninfo::text, p_pa_connretry::text); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.storePath (p_pa_server int4, p_pa_client int4, p_pa_conninfo text, p_pa_connretry int4) is 461s 'FUNCTION storePath (pa_server, pa_client, pa_conninfo, pa_connretry) 461s 461s Generate the STORE_PATH event indicating that node pa_client can 461s access node pa_server using DSN pa_conninfo'; 461s COMMENT 461s create or replace function public.storePath_int (p_pa_server int4, p_pa_client int4, p_pa_conninfo text, p_pa_connretry int4) 461s returns int4 461s as $$ 461s declare 461s v_dummy int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Check if the path already exists 461s -- ---- 461s select 1 into v_dummy 461s from public.sl_path 461s where pa_server = p_pa_server 461s and pa_client = p_pa_client 461s for update; 461s if found then 461s -- ---- 461s -- Path exists, update pa_conninfo 461s -- ---- 461s update public.sl_path 461s set pa_conninfo = p_pa_conninfo, 461s pa_connretry = p_pa_connretry 461s where pa_server = p_pa_server 461s and pa_client = p_pa_client; 461s else 461s -- ---- 461s -- New path 461s -- 461s -- In case we receive STORE_PATH events before we know 461s -- about the nodes involved in this, we generate those nodes 461s -- as pending. 461s -- ---- 461s if not exists (select 1 from public.sl_node 461s where no_id = p_pa_server) then 461s perform public.storeNode_int (p_pa_server, ''); 461s end if; 461s if not exists (select 1 from public.sl_node 461s where no_id = p_pa_client) then 461s perform public.storeNode_int (p_pa_client, ''); 461s end if; 461s insert into public.sl_path 461s (pa_server, pa_client, pa_conninfo, pa_connretry) values 461s (p_pa_server, p_pa_client, p_pa_conninfo, p_pa_connretry); 461s end if; 461s 461s -- Rewrite sl_listen table 461s perform public.RebuildListenEntries(); 461s 461s return 0; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.storePath_int (p_pa_server int4, p_pa_client int4, p_pa_conninfo text, p_pa_connretry int4) is 461s 'FUNCTION storePath (pa_server, pa_client, pa_conninfo, pa_connretry) 461s 461s Process the STORE_PATH event indicating that node pa_client can 461s access node pa_server using DSN pa_conninfo'; 461s COMMENT 461s create or replace function public.dropPath (p_pa_server int4, p_pa_client int4) 461s returns bigint 461s as $$ 461s declare 461s v_row record; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- There should be no existing subscriptions. Auto unsubscribing 461s -- is considered too dangerous. 461s -- ---- 461s for v_row in select sub_set, sub_provider, sub_receiver 461s from public.sl_subscribe 461s where sub_provider = p_pa_server 461s and sub_receiver = p_pa_client 461s loop 461s raise exception 461s 'Slony-I: Path cannot be dropped, subscription of set % needs it', 461s v_row.sub_set; 461s end loop; 461s 461s -- ---- 461s -- Drop all sl_listen entries that depend on this path 461s -- ---- 461s for v_row in select li_origin, li_provider, li_receiver 461s from public.sl_listen 461s where li_provider = p_pa_server 461s and li_receiver = p_pa_client 461s loop 461s perform public.dropListen( 461s v_row.li_origin, v_row.li_provider, v_row.li_receiver); 461s end loop; 461s 461s -- ---- 461s -- Now drop the path and create the event 461s -- ---- 461s perform public.dropPath_int(p_pa_server, p_pa_client); 461s 461s -- Rewrite sl_listen table 461s perform public.RebuildListenEntries(); 461s 461s return public.createEvent ('_main', 'DROP_PATH', 461s p_pa_server::text, p_pa_client::text); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.dropPath (p_pa_server int4, p_pa_client int4) is 461s 'Generate DROP_PATH event to drop path from pa_server to pa_client'; 461s COMMENT 461s create or replace function public.dropPath_int (p_pa_server int4, p_pa_client int4) 461s returns int4 461s as $$ 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Remove any dangling sl_listen entries with the server 461s -- as provider and the client as receiver. This must have 461s -- been cleared out before, but obviously was not. 461s -- ---- 461s delete from public.sl_listen 461s where li_provider = p_pa_server 461s and li_receiver = p_pa_client; 461s 461s delete from public.sl_path 461s where pa_server = p_pa_server 461s and pa_client = p_pa_client; 461s 461s if found then 461s -- Rewrite sl_listen table 461s perform public.RebuildListenEntries(); 461s 461s return 1; 461s else 461s -- Rewrite sl_listen table 461s perform public.RebuildListenEntries(); 461s 461s return 0; 461s end if; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.dropPath_int (p_pa_server int4, p_pa_client int4) is 461s 'Process DROP_PATH event to drop path from pa_server to pa_client'; 461s COMMENT 461s create or replace function public.storeListen (p_origin int4, p_provider int4, p_receiver int4) 461s returns bigint 461s as $$ 461s begin 461s perform public.storeListen_int (p_origin, p_provider, p_receiver); 461s return public.createEvent ('_main', 'STORE_LISTEN', 461s p_origin::text, p_provider::text, p_receiver::text); 461s end; 461s $$ language plpgsql 461s called on null input; 461s CREATE FUNCTION 461s comment on function public.storeListen(p_origin int4, p_provider int4, p_receiver int4) is 461s 'FUNCTION storeListen (li_origin, li_provider, li_receiver) 461s 461s generate STORE_LISTEN event, indicating that receiver node li_receiver 461s listens to node li_provider in order to get messages coming from node 461s li_origin.'; 461s COMMENT 461s create or replace function public.storeListen_int (p_li_origin int4, p_li_provider int4, p_li_receiver int4) 461s returns int4 461s as $$ 461s declare 461s v_exists int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s select 1 into v_exists 461s from public.sl_listen 461s where li_origin = p_li_origin 461s and li_provider = p_li_provider 461s and li_receiver = p_li_receiver; 461s if not found then 461s -- ---- 461s -- In case we receive STORE_LISTEN events before we know 461s -- about the nodes involved in this, we generate those nodes 461s -- as pending. 461s -- ---- 461s if not exists (select 1 from public.sl_node 461s where no_id = p_li_origin) then 461s perform public.storeNode_int (p_li_origin, ''); 461s end if; 461s if not exists (select 1 from public.sl_node 461s where no_id = p_li_provider) then 461s perform public.storeNode_int (p_li_provider, ''); 461s end if; 461s if not exists (select 1 from public.sl_node 461s where no_id = p_li_receiver) then 461s perform public.storeNode_int (p_li_receiver, ''); 461s end if; 461s 461s insert into public.sl_listen 461s (li_origin, li_provider, li_receiver) values 461s (p_li_origin, p_li_provider, p_li_receiver); 461s end if; 461s 461s return 0; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.storeListen_int(p_li_origin int4, p_li_provider int4, p_li_receiver int4) is 461s 'FUNCTION storeListen_int (li_origin, li_provider, li_receiver) 461s 461s Process STORE_LISTEN event, indicating that receiver node li_receiver 461s listens to node li_provider in order to get messages coming from node 461s li_origin.'; 461s COMMENT 461s create or replace function public.dropListen (p_li_origin int4, p_li_provider int4, p_li_receiver int4) 461s returns bigint 461s as $$ 461s begin 461s perform public.dropListen_int(p_li_origin, 461s p_li_provider, p_li_receiver); 461s 461s return public.createEvent ('_main', 'DROP_LISTEN', 461s p_li_origin::text, p_li_provider::text, p_li_receiver::text); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.dropListen(p_li_origin int4, p_li_provider int4, p_li_receiver int4) is 461s 'dropListen (li_origin, li_provider, li_receiver) 461s 461s Generate the DROP_LISTEN event.'; 461s COMMENT 461s create or replace function public.dropListen_int (p_li_origin int4, p_li_provider int4, p_li_receiver int4) 461s returns int4 461s as $$ 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s delete from public.sl_listen 461s where li_origin = p_li_origin 461s and li_provider = p_li_provider 461s and li_receiver = p_li_receiver; 461s if found then 461s return 1; 461s else 461s return 0; 461s end if; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.dropListen_int(p_li_origin int4, p_li_provider int4, p_li_receiver int4) is 461s 'dropListen (li_origin, li_provider, li_receiver) 461s 461s Process the DROP_LISTEN event, deleting the sl_listen entry for 461s the indicated (origin,provider,receiver) combination.'; 461s COMMENT 461s create or replace function public.storeSet (p_set_id int4, p_set_comment text) 461s returns bigint 461s as $$ 461s declare 461s v_local_node_id int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s v_local_node_id := public.getLocalNodeId('_main'); 461s 461s insert into public.sl_set 461s (set_id, set_origin, set_comment) values 461s (p_set_id, v_local_node_id, p_set_comment); 461s 461s return public.createEvent('_main', 'STORE_SET', 461s p_set_id::text, v_local_node_id::text, p_set_comment::text); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.storeSet(p_set_id int4, p_set_comment text) is 461s 'Generate STORE_SET event for set set_id with human readable comment set_comment'; 461s COMMENT 461s create or replace function public.storeSet_int (p_set_id int4, p_set_origin int4, p_set_comment text) 461s returns int4 461s as $$ 461s declare 461s v_dummy int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s select 1 into v_dummy 461s from public.sl_set 461s where set_id = p_set_id 461s for update; 461s if found then 461s update public.sl_set 461s set set_comment = p_set_comment 461s where set_id = p_set_id; 461s else 461s if not exists (select 1 from public.sl_node 461s where no_id = p_set_origin) then 461s perform public.storeNode_int (p_set_origin, ''); 461s end if; 461s insert into public.sl_set 461s (set_id, set_origin, set_comment) values 461s (p_set_id, p_set_origin, p_set_comment); 461s end if; 461s 461s -- Run addPartialLogIndices() to try to add indices to unused sl_log_? table 461s perform public.addPartialLogIndices(); 461s 461s return p_set_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.storeSet_int(p_set_id int4, p_set_origin int4, p_set_comment text) is 461s 'storeSet_int (set_id, set_origin, set_comment) 461s 461s Process the STORE_SET event, indicating the new set with given ID, 461s origin node, and human readable comment.'; 461s COMMENT 461s create or replace function public.lockSet (p_set_id int4) 461s returns int4 461s as $$ 461s declare 461s v_local_node_id int4; 461s v_set_row record; 461s v_tab_row record; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Check that the set exists and that we are the origin 461s -- and that it is not already locked. 461s -- ---- 461s v_local_node_id := public.getLocalNodeId('_main'); 461s select * into v_set_row from public.sl_set 461s where set_id = p_set_id 461s for update; 461s if not found then 461s raise exception 'Slony-I: set % not found', p_set_id; 461s end if; 461s if v_set_row.set_origin <> v_local_node_id then 461s raise exception 'Slony-I: set % does not originate on local node', 461s p_set_id; 461s end if; 461s if v_set_row.set_locked notnull then 461s raise exception 'Slony-I: set % is already locked', p_set_id; 461s end if; 461s 461s -- ---- 461s -- Place the lockedSet trigger on all tables in the set. 461s -- ---- 461s for v_tab_row in select T.tab_id, 461s public.slon_quote_brute(PGN.nspname) || '.' || 461s public.slon_quote_brute(PGC.relname) as tab_fqname 461s from public.sl_table T, 461s "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN 461s where T.tab_set = p_set_id 461s and T.tab_reloid = PGC.oid 461s and PGC.relnamespace = PGN.oid 461s order by tab_id 461s loop 461s execute 'create trigger "_main_lockedset" ' || 461s 'before insert or update or delete on ' || 461s v_tab_row.tab_fqname || ' for each row execute procedure 461s public.lockedSet (''_main'');'; 461s end loop; 461s 461s -- ---- 461s -- Remember our snapshots xmax as for the set locking 461s -- ---- 461s update public.sl_set 461s set set_locked = "pg_catalog".txid_snapshot_xmax("pg_catalog".txid_current_snapshot()) 461s where set_id = p_set_id; 461s 461s return p_set_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.lockSet(p_set_id int4) is 461s 'lockSet(set_id) 461s 461s Add a special trigger to all tables of a set that disables access to 461s it.'; 461s COMMENT 461s create or replace function public.unlockSet (p_set_id int4) 461s returns int4 461s as $$ 461s declare 461s v_local_node_id int4; 461s v_set_row record; 461s v_tab_row record; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Check that the set exists and that we are the origin 461s -- and that it is not already locked. 461s -- ---- 461s v_local_node_id := public.getLocalNodeId('_main'); 461s select * into v_set_row from public.sl_set 461s where set_id = p_set_id 461s for update; 461s if not found then 461s raise exception 'Slony-I: set % not found', p_set_id; 461s end if; 461s if v_set_row.set_origin <> v_local_node_id then 461s raise exception 'Slony-I: set % does not originate on local node', 461s p_set_id; 461s end if; 461s if v_set_row.set_locked isnull then 461s raise exception 'Slony-I: set % is not locked', p_set_id; 461s end if; 461s 461s -- ---- 461s -- Drop the lockedSet trigger from all tables in the set. 461s -- ---- 461s for v_tab_row in select T.tab_id, 461s public.slon_quote_brute(PGN.nspname) || '.' || 461s public.slon_quote_brute(PGC.relname) as tab_fqname 461s from public.sl_table T, 461s "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN 461s where T.tab_set = p_set_id 461s and T.tab_reloid = PGC.oid 461s and PGC.relnamespace = PGN.oid 461s order by tab_id 461s loop 461s execute 'drop trigger "_main_lockedset" ' || 461s 'on ' || v_tab_row.tab_fqname; 461s end loop; 461s 461s -- ---- 461s -- Clear out the set_locked field 461s -- ---- 461s update public.sl_set 461s set set_locked = NULL 461s where set_id = p_set_id; 461s 461s return p_set_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.unlockSet(p_set_id int4) is 461s 'Remove the special trigger from all tables of a set that disables access to it.'; 461s COMMENT 461s create or replace function public.moveSet (p_set_id int4, p_new_origin int4) 461s returns bigint 461s as $$ 461s declare 461s v_local_node_id int4; 461s v_set_row record; 461s v_sub_row record; 461s v_sync_seqno int8; 461s v_lv_row record; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Check that the set is locked and that this locking 461s -- happened long enough ago. 461s -- ---- 461s v_local_node_id := public.getLocalNodeId('_main'); 461s select * into v_set_row from public.sl_set 461s where set_id = p_set_id 461s for update; 461s if not found then 461s raise exception 'Slony-I: set % not found', p_set_id; 461s end if; 461s if v_set_row.set_origin <> v_local_node_id then 461s raise exception 'Slony-I: set % does not originate on local node', 461s p_set_id; 461s end if; 461s if v_set_row.set_locked isnull then 461s raise exception 'Slony-I: set % is not locked', p_set_id; 461s end if; 461s if v_set_row.set_locked > "pg_catalog".txid_snapshot_xmin("pg_catalog".txid_current_snapshot()) then 461s raise exception 'Slony-I: cannot move set % yet, transactions < % are still in progress', 461s p_set_id, v_set_row.set_locked; 461s end if; 461s 461s -- ---- 461s -- Unlock the set 461s -- ---- 461s perform public.unlockSet(p_set_id); 461s 461s -- ---- 461s -- Check that the new_origin is an active subscriber of the set 461s -- ---- 461s select * into v_sub_row from public.sl_subscribe 461s where sub_set = p_set_id 461s and sub_receiver = p_new_origin; 461s if not found then 461s raise exception 'Slony-I: set % is not subscribed by node %', 461s p_set_id, p_new_origin; 461s end if; 461s if not v_sub_row.sub_active then 461s raise exception 'Slony-I: subsctiption of node % for set % is inactive', 461s p_new_origin, p_set_id; 461s end if; 461s 461s -- ---- 461s -- Reconfigure everything 461s -- ---- 461s perform public.moveSet_int(p_set_id, v_local_node_id, 461s p_new_origin, 0); 461s 461s perform public.RebuildListenEntries(); 461s 461s -- ---- 461s -- At this time we hold access exclusive locks for every table 461s -- in the set. But we did move the set to the new origin, so the 461s -- createEvent() we are doing now will not record the sequences. 461s -- ---- 461s v_sync_seqno := public.createEvent('_main', 'SYNC'); 461s insert into public.sl_seqlog 461s (seql_seqid, seql_origin, seql_ev_seqno, seql_last_value) 461s select seq_id, v_local_node_id, v_sync_seqno, seq_last_value 461s from public.sl_seqlastvalue 461s where seq_set = p_set_id; 461s 461s -- ---- 461s -- Finally we generate the real event 461s -- ---- 461s return public.createEvent('_main', 'MOVE_SET', 461s p_set_id::text, v_local_node_id::text, p_new_origin::text); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.moveSet(p_set_id int4, p_new_origin int4) is 461s 'moveSet(set_id, new_origin) 461s 461s Generate MOVE_SET event to request that the origin for set set_id be moved to node new_origin'; 461s COMMENT 461s create or replace function public.moveSet_int (p_set_id int4, p_old_origin int4, p_new_origin int4, p_wait_seqno int8) 461s returns int4 461s as $$ 461s declare 461s v_local_node_id int4; 461s v_tab_row record; 461s v_sub_row record; 461s v_sub_node int4; 461s v_sub_last int4; 461s v_sub_next int4; 461s v_last_sync int8; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Get our local node ID 461s -- ---- 461s v_local_node_id := public.getLocalNodeId('_main'); 461s 461s -- On the new origin, raise an event - ACCEPT_SET 461s if v_local_node_id = p_new_origin then 461s -- Create a SYNC event as well so that the ACCEPT_SET has 461s -- the same snapshot as the last SYNC generated by the new 461s -- origin. This snapshot will be used by other nodes to 461s -- finalize the setsync status. 461s perform public.createEvent('_main', 'SYNC', NULL); 461s perform public.createEvent('_main', 'ACCEPT_SET', 461s p_set_id::text, p_old_origin::text, 461s p_new_origin::text, p_wait_seqno::text); 461s end if; 461s 461s -- ---- 461s -- Next we have to reverse the subscription path 461s -- ---- 461s v_sub_last = p_new_origin; 461s select sub_provider into v_sub_node 461s from public.sl_subscribe 461s where sub_set = p_set_id 461s and sub_receiver = p_new_origin; 461s if not found then 461s raise exception 'Slony-I: subscription path broken in moveSet_int'; 461s end if; 461s while v_sub_node <> p_old_origin loop 461s -- ---- 461s -- Tracing node by node, the old receiver is now in 461s -- v_sub_last and the old provider is in v_sub_node. 461s -- ---- 461s 461s -- ---- 461s -- Get the current provider of this node as next 461s -- and change the provider to the previous one in 461s -- the reverse chain. 461s -- ---- 461s select sub_provider into v_sub_next 461s from public.sl_subscribe 461s where sub_set = p_set_id 461s and sub_receiver = v_sub_node 461s for update; 461s if not found then 461s raise exception 'Slony-I: subscription path broken in moveSet_int'; 461s end if; 461s update public.sl_subscribe 461s set sub_provider = v_sub_last 461s where sub_set = p_set_id 461s and sub_receiver = v_sub_node 461s and sub_receiver <> v_sub_last; 461s 461s v_sub_last = v_sub_node; 461s v_sub_node = v_sub_next; 461s end loop; 461s 461s -- ---- 461s -- This includes creating a subscription for the old origin 461s -- ---- 461s insert into public.sl_subscribe 461s (sub_set, sub_provider, sub_receiver, 461s sub_forward, sub_active) 461s values (p_set_id, v_sub_last, p_old_origin, true, true); 461s if v_local_node_id = p_old_origin then 461s select coalesce(max(ev_seqno), 0) into v_last_sync 461s from public.sl_event 461s where ev_origin = p_new_origin 461s and ev_type = 'SYNC'; 461s if v_last_sync > 0 then 461s insert into public.sl_setsync 461s (ssy_setid, ssy_origin, ssy_seqno, 461s ssy_snapshot, ssy_action_list) 461s select p_set_id, p_new_origin, v_last_sync, 461s ev_snapshot, NULL 461s from public.sl_event 461s where ev_origin = p_new_origin 461s and ev_seqno = v_last_sync; 461s else 461s insert into public.sl_setsync 461s (ssy_setid, ssy_origin, ssy_seqno, 461s ssy_snapshot, ssy_action_list) 461s values (p_set_id, p_new_origin, '0', 461s '1:1:', NULL); 461s end if; 461s end if; 461s 461s -- ---- 461s -- Now change the ownership of the set. 461s -- ---- 461s update public.sl_set 461s set set_origin = p_new_origin 461s where set_id = p_set_id; 461s 461s -- ---- 461s -- On the new origin, delete the obsolete setsync information 461s -- and the subscription. 461s -- ---- 461s if v_local_node_id = p_new_origin then 461s delete from public.sl_setsync 461s where ssy_setid = p_set_id; 461s else 461s if v_local_node_id <> p_old_origin then 461s -- 461s -- On every other node, change the setsync so that it will 461s -- pick up from the new origins last known sync. 461s -- 461s delete from public.sl_setsync 461s where ssy_setid = p_set_id; 461s select coalesce(max(ev_seqno), 0) into v_last_sync 461s from public.sl_event 461s where ev_origin = p_new_origin 461s and ev_type = 'SYNC'; 461s if v_last_sync > 0 then 461s insert into public.sl_setsync 461s (ssy_setid, ssy_origin, ssy_seqno, 461s ssy_snapshot, ssy_action_list) 461s select p_set_id, p_new_origin, v_last_sync, 461s ev_snapshot, NULL 461s from public.sl_event 461s where ev_origin = p_new_origin 461s and ev_seqno = v_last_sync; 461s else 461s insert into public.sl_setsync 461s (ssy_setid, ssy_origin, ssy_seqno, 461s ssy_snapshot, ssy_action_list) 461s values (p_set_id, p_new_origin, 461s '0', '1:1:', NULL); 461s end if; 461s end if; 461s end if; 461s delete from public.sl_subscribe 461s where sub_set = p_set_id 461s and sub_receiver = p_new_origin; 461s 461s -- Regenerate sl_listen since we revised the subscriptions 461s perform public.RebuildListenEntries(); 461s 461s -- Run addPartialLogIndices() to try to add indices to unused sl_log_? table 461s perform public.addPartialLogIndices(); 461s 461s -- ---- 461s -- If we are the new or old origin, we have to 461s -- adjust the log and deny access trigger configuration. 461s -- ---- 461s if v_local_node_id = p_old_origin or v_local_node_id = p_new_origin then 461s for v_tab_row in select tab_id from public.sl_table 461s where tab_set = p_set_id 461s order by tab_id 461s loop 461s perform public.alterTableConfigureTriggers(v_tab_row.tab_id); 461s end loop; 461s end if; 461s 461s return p_set_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.moveSet_int(p_set_id int4, p_old_origin int4, p_new_origin int4, p_wait_seqno int8) is 461s 'moveSet(set_id, old_origin, new_origin, wait_seqno) 461s 461s Process MOVE_SET event to request that the origin for set set_id be 461s moved from old_origin to node new_origin'; 461s COMMENT 461s create or replace function public.dropSet (p_set_id int4) 461s returns bigint 461s as $$ 461s declare 461s v_origin int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Check that the set exists and originates here 461s -- ---- 461s select set_origin into v_origin from public.sl_set 461s where set_id = p_set_id; 461s if not found then 461s raise exception 'Slony-I: set % not found', p_set_id; 461s end if; 461s if v_origin != public.getLocalNodeId('_main') then 461s raise exception 'Slony-I: set % does not originate on local node', 461s p_set_id; 461s end if; 461s 461s -- ---- 461s -- Call the internal drop set functionality and generate the event 461s -- ---- 461s perform public.dropSet_int(p_set_id); 461s return public.createEvent('_main', 'DROP_SET', 461s p_set_id::text); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.dropSet(p_set_id int4) is 461s 'Generate DROP_SET event to drop replication of set set_id'; 461s COMMENT 461s create or replace function public.dropSet_int (p_set_id int4) 461s returns int4 461s as $$ 461s declare 461s v_tab_row record; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Restore all tables original triggers and rules and remove 461s -- our replication stuff. 461s -- ---- 461s for v_tab_row in select tab_id from public.sl_table 461s where tab_set = p_set_id 461s order by tab_id 461s loop 461s perform public.alterTableDropTriggers(v_tab_row.tab_id); 461s end loop; 461s 461s -- ---- 461s -- Remove all traces of the set configuration 461s -- ---- 461s delete from public.sl_sequence 461s where seq_set = p_set_id; 461s delete from public.sl_table 461s where tab_set = p_set_id; 461s delete from public.sl_subscribe 461s where sub_set = p_set_id; 461s delete from public.sl_setsync 461s where ssy_setid = p_set_id; 461s delete from public.sl_set 461s where set_id = p_set_id; 461s 461s -- Regenerate sl_listen since we revised the subscriptions 461s perform public.RebuildListenEntries(); 461s 461s -- Run addPartialLogIndices() to try to add indices to unused sl_log_? table 461s perform public.addPartialLogIndices(); 461s 461s return p_set_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.dropSet(p_set_id int4) is 461s 'Process DROP_SET event to drop replication of set set_id. This involves: 461s - Removing log and deny access triggers 461s - Removing all traces of the set configuration, including sequences, tables, subscribers, syncs, and the set itself'; 461s COMMENT 461s create or replace function public.mergeSet (p_set_id int4, p_add_id int4) 461s returns bigint 461s as $$ 461s declare 461s v_origin int4; 461s in_progress boolean; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Check that both sets exist and originate here 461s -- ---- 461s if p_set_id = p_add_id then 461s raise exception 'Slony-I: merged set ids cannot be identical'; 461s end if; 461s select set_origin into v_origin from public.sl_set 461s where set_id = p_set_id; 461s if not found then 461s raise exception 'Slony-I: set % not found', p_set_id; 461s end if; 461s if v_origin != public.getLocalNodeId('_main') then 461s raise exception 'Slony-I: set % does not originate on local node', 461s p_set_id; 461s end if; 461s 461s select set_origin into v_origin from public.sl_set 461s where set_id = p_add_id; 461s if not found then 461s raise exception 'Slony-I: set % not found', p_add_id; 461s end if; 461s if v_origin != public.getLocalNodeId('_main') then 461s raise exception 'Slony-I: set % does not originate on local node', 461s p_add_id; 461s end if; 461s 461s -- ---- 461s -- Check that both sets are subscribed by the same set of nodes 461s -- ---- 461s if exists (select true from public.sl_subscribe SUB1 461s where SUB1.sub_set = p_set_id 461s and SUB1.sub_receiver not in (select SUB2.sub_receiver 461s from public.sl_subscribe SUB2 461s where SUB2.sub_set = p_add_id)) 461s then 461s raise exception 'Slony-I: subscriber lists of set % and % are different', 461s p_set_id, p_add_id; 461s end if; 461s 461s if exists (select true from public.sl_subscribe SUB1 461s where SUB1.sub_set = p_add_id 461s and SUB1.sub_receiver not in (select SUB2.sub_receiver 461s from public.sl_subscribe SUB2 461s where SUB2.sub_set = p_set_id)) 461s then 461s raise exception 'Slony-I: subscriber lists of set % and % are different', 461s p_add_id, p_set_id; 461s end if; 461s 461s -- ---- 461s -- Check that all ENABLE_SUBSCRIPTION events for the set are confirmed 461s -- ---- 461s select public.isSubscriptionInProgress(p_add_id) into in_progress ; 461s 461s if in_progress then 461s raise exception 'Slony-I: set % has subscriptions in progress - cannot merge', 461s p_add_id; 461s end if; 461s 461s -- ---- 461s -- Create a SYNC event, merge the sets, create a MERGE_SET event 461s -- ---- 461s perform public.createEvent('_main', 'SYNC', NULL); 461s perform public.mergeSet_int(p_set_id, p_add_id); 461s return public.createEvent('_main', 'MERGE_SET', 461s p_set_id::text, p_add_id::text); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.mergeSet(p_set_id int4, p_add_id int4) is 461s 'Generate MERGE_SET event to request that sets be merged together. 461s 461s Both sets must exist, and originate on the same node. They must be 461s subscribed by the same set of nodes.'; 461s COMMENT 461s create or replace function public.isSubscriptionInProgress(p_add_id int4) 461s returns boolean 461s as $$ 461s begin 461s if exists (select true from public.sl_event 461s where ev_type = 'ENABLE_SUBSCRIPTION' 461s and ev_data1 = p_add_id::text 461s and ev_seqno > (select max(con_seqno) from public.sl_confirm 461s where con_origin = ev_origin 461s and con_received::text = ev_data3)) 461s then 461s return true; 461s else 461s return false; 461s end if; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.isSubscriptionInProgress(p_add_id int4) is 461s 'Checks to see if a subscription for the indicated set is in progress. 461s Returns true if a subscription is in progress. Otherwise false'; 461s COMMENT 461s create or replace function public.mergeSet_int (p_set_id int4, p_add_id int4) 461s returns int4 461s as $$ 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s update public.sl_sequence 461s set seq_set = p_set_id 461s where seq_set = p_add_id; 461s update public.sl_table 461s set tab_set = p_set_id 461s where tab_set = p_add_id; 461s delete from public.sl_subscribe 461s where sub_set = p_add_id; 461s delete from public.sl_setsync 461s where ssy_setid = p_add_id; 461s delete from public.sl_set 461s where set_id = p_add_id; 461s 461s return p_set_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.mergeSet_int(p_set_id int4, p_add_id int4) is 461s 'mergeSet_int(set_id, add_id) - Perform MERGE_SET event, merging all objects from 461s set add_id into set set_id.'; 461s COMMENT 461s create or replace function public.setAddTable(p_set_id int4, p_tab_id int4, p_fqname text, p_tab_idxname name, p_tab_comment text) 461s returns bigint 461s as $$ 461s declare 461s v_set_origin int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Check that we are the origin of the set 461s -- ---- 461s select set_origin into v_set_origin 461s from public.sl_set 461s where set_id = p_set_id; 461s if not found then 461s raise exception 'Slony-I: setAddTable(): set % not found', p_set_id; 461s end if; 461s if v_set_origin != public.getLocalNodeId('_main') then 461s raise exception 'Slony-I: setAddTable(): set % has remote origin', p_set_id; 461s end if; 461s 461s if exists (select true from public.sl_subscribe 461s where sub_set = p_set_id) 461s then 461s raise exception 'Slony-I: cannot add table to currently subscribed set % - must attach to an unsubscribed set', 461s p_set_id; 461s end if; 461s 461s -- ---- 461s -- Add the table to the set and generate the SET_ADD_TABLE event 461s -- ---- 461s perform public.setAddTable_int(p_set_id, p_tab_id, p_fqname, 461s p_tab_idxname, p_tab_comment); 461s return public.createEvent('_main', 'SET_ADD_TABLE', 461s p_set_id::text, p_tab_id::text, p_fqname::text, 461s p_tab_idxname::text, p_tab_comment::text); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.setAddTable(p_set_id int4, p_tab_id int4, p_fqname text, p_tab_idxname name, p_tab_comment text) is 461s 'setAddTable (set_id, tab_id, tab_fqname, tab_idxname, tab_comment) 461s 461s Add table tab_fqname to replication set on origin node, and generate 461s SET_ADD_TABLE event to allow this to propagate to other nodes. 461s 461s Note that the table id, tab_id, must be unique ACROSS ALL SETS.'; 461s COMMENT 461s create or replace function public.setAddTable_int(p_set_id int4, p_tab_id int4, p_fqname text, p_tab_idxname name, p_tab_comment text) 461s returns int4 461s as $$ 461s declare 461s v_tab_relname name; 461s v_tab_nspname name; 461s v_local_node_id int4; 461s v_set_origin int4; 461s v_sub_provider int4; 461s v_relkind char; 461s v_tab_reloid oid; 461s v_pkcand_nn boolean; 461s v_prec record; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- For sets with a remote origin, check that we are subscribed 461s -- to that set. Otherwise we ignore the table because it might 461s -- not even exist in our database. 461s -- ---- 461s v_local_node_id := public.getLocalNodeId('_main'); 461s select set_origin into v_set_origin 461s from public.sl_set 461s where set_id = p_set_id; 461s if not found then 461s raise exception 'Slony-I: setAddTable_int(): set % not found', 461s p_set_id; 461s end if; 461s if v_set_origin != v_local_node_id then 461s select sub_provider into v_sub_provider 461s from public.sl_subscribe 461s where sub_set = p_set_id 461s and sub_receiver = public.getLocalNodeId('_main'); 461s if not found then 461s return 0; 461s end if; 461s end if; 461s 461s -- ---- 461s -- Get the tables OID and check that it is a real table 461s -- ---- 461s select PGC.oid, PGC.relkind, PGC.relname, PGN.nspname into v_tab_reloid, v_relkind, v_tab_relname, v_tab_nspname 461s from "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN 461s where PGC.relnamespace = PGN.oid 461s and public.slon_quote_input(p_fqname) = public.slon_quote_brute(PGN.nspname) || 461s '.' || public.slon_quote_brute(PGC.relname); 461s if not found then 461s raise exception 'Slony-I: setAddTable_int(): table % not found', 461s p_fqname; 461s end if; 461s if v_relkind != 'r' then 461s raise exception 'Slony-I: setAddTable_int(): % is not a regular table', 461s p_fqname; 461s end if; 461s 461s if not exists (select indexrelid 461s from "pg_catalog".pg_index PGX, "pg_catalog".pg_class PGC 461s where PGX.indrelid = v_tab_reloid 461s and PGX.indexrelid = PGC.oid 461s and PGC.relname = p_tab_idxname) 461s then 461s raise exception 'Slony-I: setAddTable_int(): table % has no index %', 461s p_fqname, p_tab_idxname; 461s end if; 461s 461s -- ---- 461s -- Verify that the columns in the PK (or candidate) are not NULLABLE 461s -- ---- 461s 461s v_pkcand_nn := 'f'; 461s for v_prec in select attname from "pg_catalog".pg_attribute where attrelid = 461s (select oid from "pg_catalog".pg_class where oid = v_tab_reloid) 461s and attname in (select attname from "pg_catalog".pg_attribute where 461s attrelid = (select oid from "pg_catalog".pg_class PGC, 461s "pg_catalog".pg_index PGX where 461s PGC.relname = p_tab_idxname and PGX.indexrelid=PGC.oid and 461s PGX.indrelid = v_tab_reloid)) and attnotnull <> 't' 461s loop 461s raise notice 'Slony-I: setAddTable_int: table % PK column % nullable', p_fqname, v_prec.attname; 461s v_pkcand_nn := 't'; 461s end loop; 461s if v_pkcand_nn then 461s raise exception 'Slony-I: setAddTable_int: table % not replicable!', p_fqname; 461s end if; 461s 461s select * into v_prec from public.sl_table where tab_id = p_tab_id; 461s if not found then 461s v_pkcand_nn := 't'; -- No-op -- All is well 461s else 461s raise exception 'Slony-I: setAddTable_int: table id % has already been assigned!', p_tab_id; 461s end if; 461s 461s -- ---- 461s -- Add the table to sl_table and create the trigger on it. 461s -- ---- 461s insert into public.sl_table 461s (tab_id, tab_reloid, tab_relname, tab_nspname, 461s tab_set, tab_idxname, tab_altered, tab_comment) 461s values 461s (p_tab_id, v_tab_reloid, v_tab_relname, v_tab_nspname, 461s p_set_id, p_tab_idxname, false, p_tab_comment); 461s perform public.alterTableAddTriggers(p_tab_id); 461s 461s return p_tab_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.setAddTable_int(p_set_id int4, p_tab_id int4, p_fqname text, p_tab_idxname name, p_tab_comment text) is 461s 'setAddTable_int (set_id, tab_id, tab_fqname, tab_idxname, tab_comment) 461s 461s This function processes the SET_ADD_TABLE event on remote nodes, 461s adding a table to replication if the remote node is subscribing to its 461s replication set.'; 461s COMMENT 461s create or replace function public.setDropTable(p_tab_id int4) 461s returns bigint 461s as $$ 461s declare 461s v_set_id int4; 461s v_set_origin int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Determine the set_id 461s -- ---- 461s select tab_set into v_set_id from public.sl_table where tab_id = p_tab_id; 461s 461s -- ---- 461s -- Ensure table exists 461s -- ---- 461s if not found then 461s raise exception 'Slony-I: setDropTable_int(): table % not found', 461s p_tab_id; 461s end if; 461s 461s -- ---- 461s -- Check that we are the origin of the set 461s -- ---- 461s select set_origin into v_set_origin 461s from public.sl_set 461s where set_id = v_set_id; 461s if not found then 461s raise exception 'Slony-I: setDropTable(): set % not found', v_set_id; 461s end if; 461s if v_set_origin != public.getLocalNodeId('_main') then 461s raise exception 'Slony-I: setDropTable(): set % has remote origin', v_set_id; 461s end if; 461s 461s -- ---- 461s -- Drop the table from the set and generate the SET_ADD_TABLE event 461s -- ---- 461s perform public.setDropTable_int(p_tab_id); 461s return public.createEvent('_main', 'SET_DROP_TABLE', 461s p_tab_id::text); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.setDropTable(p_tab_id int4) is 461s 'setDropTable (tab_id) 461s 461s Drop table tab_id from set on origin node, and generate SET_DROP_TABLE 461s event to allow this to propagate to other nodes.'; 461s COMMENT 461s create or replace function public.setDropTable_int(p_tab_id int4) 461s returns int4 461s as $$ 461s declare 461s v_set_id int4; 461s v_local_node_id int4; 461s v_set_origin int4; 461s v_sub_provider int4; 461s v_tab_reloid oid; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Determine the set_id 461s -- ---- 461s select tab_set into v_set_id from public.sl_table where tab_id = p_tab_id; 461s 461s -- ---- 461s -- Ensure table exists 461s -- ---- 461s if not found then 461s return 0; 461s end if; 461s 461s -- ---- 461s -- For sets with a remote origin, check that we are subscribed 461s -- to that set. Otherwise we ignore the table because it might 461s -- not even exist in our database. 461s -- ---- 461s v_local_node_id := public.getLocalNodeId('_main'); 461s select set_origin into v_set_origin 461s from public.sl_set 461s where set_id = v_set_id; 461s if not found then 461s raise exception 'Slony-I: setDropTable_int(): set % not found', 461s v_set_id; 461s end if; 461s if v_set_origin != v_local_node_id then 461s select sub_provider into v_sub_provider 461s from public.sl_subscribe 461s where sub_set = v_set_id 461s and sub_receiver = public.getLocalNodeId('_main'); 461s if not found then 461s return 0; 461s end if; 461s end if; 461s 461s -- ---- 461s -- Drop the table from sl_table and drop trigger from it. 461s -- ---- 461s perform public.alterTableDropTriggers(p_tab_id); 461s delete from public.sl_table where tab_id = p_tab_id; 461s return p_tab_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.setDropTable_int(p_tab_id int4) is 461s 'setDropTable_int (tab_id) 461s 461s This function processes the SET_DROP_TABLE event on remote nodes, 461s dropping a table from replication if the remote node is subscribing to 461s its replication set.'; 461s COMMENT 461s create or replace function public.setAddSequence (p_set_id int4, p_seq_id int4, p_fqname text, p_seq_comment text) 461s returns bigint 461s as $$ 461s declare 461s v_set_origin int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Check that we are the origin of the set 461s -- ---- 461s select set_origin into v_set_origin 461s from public.sl_set 461s where set_id = p_set_id; 461s if not found then 461s raise exception 'Slony-I: setAddSequence(): set % not found', p_set_id; 461s end if; 461s if v_set_origin != public.getLocalNodeId('_main') then 461s raise exception 'Slony-I: setAddSequence(): set % has remote origin - submit to origin node', p_set_id; 461s end if; 461s 461s if exists (select true from public.sl_subscribe 461s where sub_set = p_set_id) 461s then 461s raise exception 'Slony-I: cannot add sequence to currently subscribed set %', 461s p_set_id; 461s end if; 461s 461s -- ---- 461s -- Add the sequence to the set and generate the SET_ADD_SEQUENCE event 461s -- ---- 461s perform public.setAddSequence_int(p_set_id, p_seq_id, p_fqname, 461s p_seq_comment); 461s return public.createEvent('_main', 'SET_ADD_SEQUENCE', 461s p_set_id::text, p_seq_id::text, 461s p_fqname::text, p_seq_comment::text); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.setAddSequence (p_set_id int4, p_seq_id int4, p_fqname text, p_seq_comment text) is 461s 'setAddSequence (set_id, seq_id, seq_fqname, seq_comment) 461s 461s On the origin node for set set_id, add sequence seq_fqname to the 461s replication set, and raise SET_ADD_SEQUENCE to cause this to replicate 461s to subscriber nodes.'; 461s COMMENT 461s create or replace function public.setAddSequence_int(p_set_id int4, p_seq_id int4, p_fqname text, p_seq_comment text) 461s returns int4 461s as $$ 461s declare 461s v_local_node_id int4; 461s v_set_origin int4; 461s v_sub_provider int4; 461s v_relkind char; 461s v_seq_reloid oid; 461s v_seq_relname name; 461s v_seq_nspname name; 461s v_sync_row record; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- For sets with a remote origin, check that we are subscribed 461s -- to that set. Otherwise we ignore the sequence because it might 461s -- not even exist in our database. 461s -- ---- 461s v_local_node_id := public.getLocalNodeId('_main'); 461s select set_origin into v_set_origin 461s from public.sl_set 461s where set_id = p_set_id; 461s if not found then 461s raise exception 'Slony-I: setAddSequence_int(): set % not found', 461s p_set_id; 461s end if; 461s if v_set_origin != v_local_node_id then 461s select sub_provider into v_sub_provider 461s from public.sl_subscribe 461s where sub_set = p_set_id 461s and sub_receiver = public.getLocalNodeId('_main'); 461s if not found then 461s return 0; 461s end if; 461s end if; 461s 461s -- ---- 461s -- Get the sequences OID and check that it is a sequence 461s -- ---- 461s select PGC.oid, PGC.relkind, PGC.relname, PGN.nspname 461s into v_seq_reloid, v_relkind, v_seq_relname, v_seq_nspname 461s from "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN 461s where PGC.relnamespace = PGN.oid 461s and public.slon_quote_input(p_fqname) = public.slon_quote_brute(PGN.nspname) || 461s '.' || public.slon_quote_brute(PGC.relname); 461s if not found then 461s raise exception 'Slony-I: setAddSequence_int(): sequence % not found', 461s p_fqname; 461s end if; 461s if v_relkind != 'S' then 461s raise exception 'Slony-I: setAddSequence_int(): % is not a sequence', 461s p_fqname; 461s end if; 461s 461s select 1 into v_sync_row from public.sl_sequence where seq_id = p_seq_id; 461s if not found then 461s v_relkind := 'o'; -- all is OK 461s else 461s raise exception 'Slony-I: setAddSequence_int(): sequence ID % has already been assigned', p_seq_id; 461s end if; 461s 461s -- ---- 461s -- Add the sequence to sl_sequence 461s -- ---- 461s insert into public.sl_sequence 461s (seq_id, seq_reloid, seq_relname, seq_nspname, seq_set, seq_comment) 461s values 461s (p_seq_id, v_seq_reloid, v_seq_relname, v_seq_nspname, p_set_id, p_seq_comment); 461s 461s -- ---- 461s -- On the set origin, fake a sl_seqlog row for the last sync event 461s -- ---- 461s if v_set_origin = v_local_node_id then 461s for v_sync_row in select coalesce (max(ev_seqno), 0) as ev_seqno 461s from public.sl_event 461s where ev_origin = v_local_node_id 461s and ev_type = 'SYNC' 461s loop 461s insert into public.sl_seqlog 461s (seql_seqid, seql_origin, seql_ev_seqno, 461s seql_last_value) values 461s (p_seq_id, v_local_node_id, v_sync_row.ev_seqno, 461s public.sequenceLastValue(p_fqname)); 461s end loop; 461s end if; 461s 461s return p_seq_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.setAddSequence_int(p_set_id int4, p_seq_id int4, p_fqname text, p_seq_comment text) is 461s 'setAddSequence_int (set_id, seq_id, seq_fqname, seq_comment) 461s 461s This processes the SET_ADD_SEQUENCE event. On remote nodes that 461s subscribe to set_id, add the sequence to the replication set.'; 461s COMMENT 461s create or replace function public.setDropSequence (p_seq_id int4) 461s returns bigint 461s as $$ 461s declare 461s v_set_id int4; 461s v_set_origin int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Determine set id for this sequence 461s -- ---- 461s select seq_set into v_set_id from public.sl_sequence where seq_id = p_seq_id; 461s 461s -- ---- 461s -- Ensure sequence exists 461s -- ---- 461s if not found then 461s raise exception 'Slony-I: setDropSequence_int(): sequence % not found', 461s p_seq_id; 461s end if; 461s 461s -- ---- 461s -- Check that we are the origin of the set 461s -- ---- 461s select set_origin into v_set_origin 461s from public.sl_set 461s where set_id = v_set_id; 461s if not found then 461s raise exception 'Slony-I: setDropSequence(): set % not found', v_set_id; 461s end if; 461s if v_set_origin != public.getLocalNodeId('_main') then 461s raise exception 'Slony-I: setDropSequence(): set % has origin at another node - submit this to that node', v_set_id; 461s end if; 461s 461s -- ---- 461s -- Add the sequence to the set and generate the SET_ADD_SEQUENCE event 461s -- ---- 461s perform public.setDropSequence_int(p_seq_id); 461s return public.createEvent('_main', 'SET_DROP_SEQUENCE', 461s p_seq_id::text); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.setDropSequence (p_seq_id int4) is 461s 'setDropSequence (seq_id) 461s 461s On the origin node for the set, drop sequence seq_id from replication 461s set, and raise SET_DROP_SEQUENCE to cause this to replicate to 461s subscriber nodes.'; 461s COMMENT 461s create or replace function public.setDropSequence_int(p_seq_id int4) 461s returns int4 461s as $$ 461s declare 461s v_set_id int4; 461s v_local_node_id int4; 461s v_set_origin int4; 461s v_sub_provider int4; 461s v_relkind char; 461s v_sync_row record; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Determine set id for this sequence 461s -- ---- 461s select seq_set into v_set_id from public.sl_sequence where seq_id = p_seq_id; 461s 461s -- ---- 461s -- Ensure sequence exists 461s -- ---- 461s if not found then 461s return 0; 461s end if; 461s 461s -- ---- 461s -- For sets with a remote origin, check that we are subscribed 461s -- to that set. Otherwise we ignore the sequence because it might 461s -- not even exist in our database. 461s -- ---- 461s v_local_node_id := public.getLocalNodeId('_main'); 461s select set_origin into v_set_origin 461s from public.sl_set 461s where set_id = v_set_id; 461s if not found then 461s raise exception 'Slony-I: setDropSequence_int(): set % not found', 461s v_set_id; 461s end if; 461s if v_set_origin != v_local_node_id then 461s select sub_provider into v_sub_provider 461s from public.sl_subscribe 461s where sub_set = v_set_id 461s and sub_receiver = public.getLocalNodeId('_main'); 461s if not found then 461s return 0; 461s end if; 461s end if; 461s 461s -- ---- 461s -- drop the sequence from sl_sequence, sl_seqlog 461s -- ---- 461s delete from public.sl_seqlog where seql_seqid = p_seq_id; 461s delete from public.sl_sequence where seq_id = p_seq_id; 461s 461s return p_seq_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.setDropSequence_int(p_seq_id int4) is 461s 'setDropSequence_int (seq_id) 461s 461s This processes the SET_DROP_SEQUENCE event. On remote nodes that 461s subscribe to the set containing sequence seq_id, drop the sequence 461s from the replication set.'; 461s COMMENT 461s create or replace function public.setMoveTable (p_tab_id int4, p_new_set_id int4) 461s returns bigint 461s as $$ 461s declare 461s v_old_set_id int4; 461s v_origin int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Get the tables current set 461s -- ---- 461s select tab_set into v_old_set_id from public.sl_table 461s where tab_id = p_tab_id; 461s if not found then 461s raise exception 'Slony-I: table %d not found', p_tab_id; 461s end if; 461s 461s -- ---- 461s -- Check that both sets exist and originate here 461s -- ---- 461s if p_new_set_id = v_old_set_id then 461s raise exception 'Slony-I: set ids cannot be identical'; 461s end if; 461s select set_origin into v_origin from public.sl_set 461s where set_id = p_new_set_id; 461s if not found then 461s raise exception 'Slony-I: set % not found', p_new_set_id; 461s end if; 461s if v_origin != public.getLocalNodeId('_main') then 461s raise exception 'Slony-I: set % does not originate on local node', 461s p_new_set_id; 461s end if; 461s 461s select set_origin into v_origin from public.sl_set 461s where set_id = v_old_set_id; 461s if not found then 461s raise exception 'Slony-I: set % not found', v_old_set_id; 461s end if; 461s if v_origin != public.getLocalNodeId('_main') then 461s raise exception 'Slony-I: set % does not originate on local node', 461s v_old_set_id; 461s end if; 461s 461s -- ---- 461s -- Check that both sets are subscribed by the same set of nodes 461s -- ---- 461s if exists (select true from public.sl_subscribe SUB1 461s where SUB1.sub_set = p_new_set_id 461s and SUB1.sub_receiver not in (select SUB2.sub_receiver 461s from public.sl_subscribe SUB2 461s where SUB2.sub_set = v_old_set_id)) 461s then 461s raise exception 'Slony-I: subscriber lists of set % and % are different', 461s p_new_set_id, v_old_set_id; 461s end if; 461s 461s if exists (select true from public.sl_subscribe SUB1 461s where SUB1.sub_set = v_old_set_id 461s and SUB1.sub_receiver not in (select SUB2.sub_receiver 461s from public.sl_subscribe SUB2 461s where SUB2.sub_set = p_new_set_id)) 461s then 461s raise exception 'Slony-I: subscriber lists of set % and % are different', 461s v_old_set_id, p_new_set_id; 461s end if; 461s 461s -- ---- 461s -- Change the set the table belongs to 461s -- ---- 461s perform public.createEvent('_main', 'SYNC', NULL); 461s perform public.setMoveTable_int(p_tab_id, p_new_set_id); 461s return public.createEvent('_main', 'SET_MOVE_TABLE', 461s p_tab_id::text, p_new_set_id::text); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.setMoveTable(p_tab_id int4, p_new_set_id int4) is 461s 'This generates the SET_MOVE_TABLE event. If the set that the table is 461s in is identically subscribed to the set that the table is to be moved 461s into, then the SET_MOVE_TABLE event is raised.'; 461s COMMENT 461s create or replace function public.setMoveTable_int (p_tab_id int4, p_new_set_id int4) 461s returns int4 461s as $$ 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Move the table to the new set 461s -- ---- 461s update public.sl_table 461s set tab_set = p_new_set_id 461s where tab_id = p_tab_id; 461s 461s return p_tab_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.setMoveTable(p_tab_id int4, p_new_set_id int4) is 461s 'This processes the SET_MOVE_TABLE event. The table is moved 461s to the destination set.'; 461s COMMENT 461s create or replace function public.setMoveSequence (p_seq_id int4, p_new_set_id int4) 461s returns bigint 461s as $$ 461s declare 461s v_old_set_id int4; 461s v_origin int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Get the sequences current set 461s -- ---- 461s select seq_set into v_old_set_id from public.sl_sequence 461s where seq_id = p_seq_id; 461s if not found then 461s raise exception 'Slony-I: setMoveSequence(): sequence %d not found', p_seq_id; 461s end if; 461s 461s -- ---- 461s -- Check that both sets exist and originate here 461s -- ---- 461s if p_new_set_id = v_old_set_id then 461s raise exception 'Slony-I: setMoveSequence(): set ids cannot be identical'; 461s end if; 461s select set_origin into v_origin from public.sl_set 461s where set_id = p_new_set_id; 461s if not found then 461s raise exception 'Slony-I: setMoveSequence(): set % not found', p_new_set_id; 461s end if; 461s if v_origin != public.getLocalNodeId('_main') then 461s raise exception 'Slony-I: setMoveSequence(): set % does not originate on local node', 461s p_new_set_id; 461s end if; 461s 461s select set_origin into v_origin from public.sl_set 461s where set_id = v_old_set_id; 461s if not found then 461s raise exception 'Slony-I: set % not found', v_old_set_id; 461s end if; 461s if v_origin != public.getLocalNodeId('_main') then 461s raise exception 'Slony-I: set % does not originate on local node', 461s v_old_set_id; 461s end if; 461s 461s -- ---- 461s -- Check that both sets are subscribed by the same set of nodes 461s -- ---- 461s if exists (select true from public.sl_subscribe SUB1 461s where SUB1.sub_set = p_new_set_id 461s and SUB1.sub_receiver not in (select SUB2.sub_receiver 461s from public.sl_subscribe SUB2 461s where SUB2.sub_set = v_old_set_id)) 461s then 461s raise exception 'Slony-I: subscriber lists of set % and % are different', 461s p_new_set_id, v_old_set_id; 461s end if; 461s 461s if exists (select true from public.sl_subscribe SUB1 461s where SUB1.sub_set = v_old_set_id 461s and SUB1.sub_receiver not in (select SUB2.sub_receiver 461s from public.sl_subscribe SUB2 461s where SUB2.sub_set = p_new_set_id)) 461s then 461s raise exception 'Slony-I: subscriber lists of set % and % are different', 461s v_old_set_id, p_new_set_id; 461s end if; 461s 461s -- ---- 461s -- Change the set the sequence belongs to 461s -- ---- 461s perform public.setMoveSequence_int(p_seq_id, p_new_set_id); 461s return public.createEvent('_main', 'SET_MOVE_SEQUENCE', 461s p_seq_id::text, p_new_set_id::text); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.setMoveSequence (p_seq_id int4, p_new_set_id int4) is 461s 'setMoveSequence(p_seq_id, p_new_set_id) - This generates the 461s SET_MOVE_SEQUENCE event, after validation, notably that both sets 461s exist, are distinct, and have exactly the same subscription lists'; 461s COMMENT 461s create or replace function public.setMoveSequence_int (p_seq_id int4, p_new_set_id int4) 461s returns int4 461s as $$ 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Move the sequence to the new set 461s -- ---- 461s update public.sl_sequence 461s set seq_set = p_new_set_id 461s where seq_id = p_seq_id; 461s 461s return p_seq_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.setMoveSequence_int (p_seq_id int4, p_new_set_id int4) is 461s 'setMoveSequence_int(p_seq_id, p_new_set_id) - processes the 461s SET_MOVE_SEQUENCE event, moving a sequence to another replication 461s set.'; 461s COMMENT 461s create or replace function public.sequenceSetValue(p_seq_id int4, p_seq_origin int4, p_ev_seqno int8, p_last_value int8,p_ignore_missing bool) returns int4 461s as $$ 461s declare 461s v_fqname text; 461s v_found integer; 461s begin 461s -- ---- 461s -- Get the sequences fully qualified name 461s -- ---- 461s select public.slon_quote_brute(PGN.nspname) || '.' || 461s public.slon_quote_brute(PGC.relname) into v_fqname 461s from public.sl_sequence SQ, 461s "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN 461s where SQ.seq_id = p_seq_id 461s and SQ.seq_reloid = PGC.oid 461s and PGC.relnamespace = PGN.oid; 461s if not found then 461s if p_ignore_missing then 461s return null; 461s end if; 461s raise exception 'Slony-I: sequenceSetValue(): sequence % not found', p_seq_id; 461s end if; 461s 461s -- ---- 461s -- Update it to the new value 461s -- ---- 461s execute 'select setval(''' || v_fqname || 461s ''', ' || p_last_value::text || ')'; 461s 461s if p_ev_seqno is not null then 461s insert into public.sl_seqlog 461s (seql_seqid, seql_origin, seql_ev_seqno, seql_last_value) 461s values (p_seq_id, p_seq_origin, p_ev_seqno, p_last_value); 461s end if; 461s return p_seq_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.sequenceSetValue(p_seq_id int4, p_seq_origin int4, p_ev_seqno int8, p_last_value int8,p_ignore_missing bool) is 461s 'sequenceSetValue (seq_id, seq_origin, ev_seqno, last_value,ignore_missing) 461s Set sequence seq_id to have new value last_value. 461s '; 461s COMMENT 461s drop function if exists public.ddlCapture (p_statement text, p_nodes text); 461s DROP FUNCTION 461s create or replace function public.ddlCapture (p_statement text, p_nodes text) 461s returns bigint 461s as $$ 461s declare 461s c_local_node integer; 461s c_found_origin boolean; 461s c_node text; 461s c_cmdargs text[]; 461s c_nodeargs text; 461s c_delim text; 461s begin 461s c_local_node := public.getLocalNodeId('_main'); 461s 461s c_cmdargs = array_append('{}'::text[], p_statement); 461s c_nodeargs = ''; 461s if p_nodes is not null then 461s c_found_origin := 'f'; 461s -- p_nodes list needs to consist of a list of nodes that exist 461s -- and that include the current node ID 461s for c_node in select trim(node) from 461s pg_catalog.regexp_split_to_table(p_nodes, ',') as node loop 461s if not exists 461s (select 1 from public.sl_node 461s where no_id = (c_node::integer)) then 461s raise exception 'ddlcapture(%,%) - node % does not exist!', 461s p_statement, p_nodes, c_node; 461s end if; 461s 461s if c_local_node = (c_node::integer) then 461s c_found_origin := 't'; 461s end if; 461s if length(c_nodeargs)>0 then 461s c_nodeargs = c_nodeargs ||','|| c_node; 461s else 461s c_nodeargs=c_node; 461s end if; 461s end loop; 461s 461s if not c_found_origin then 461s raise exception 461s 'ddlcapture(%,%) - origin node % not included in ONLY ON list!', 461s p_statement, p_nodes, c_local_node; 461s end if; 461s end if; 461s c_cmdargs = array_append(c_cmdargs,c_nodeargs); 461s c_delim=','; 461s c_cmdargs = array_append(c_cmdargs, 461s 461s (select public.string_agg( seq_id::text || c_delim 461s || c_local_node || 461s c_delim || seq_last_value) 461s FROM ( 461s select seq_id, 461s seq_last_value from public.sl_seqlastvalue 461s where seq_origin = c_local_node) as FOO 461s where NOT public.seqtrack(seq_id,seq_last_value) is NULL)); 461s insert into public.sl_log_script 461s (log_origin, log_txid, log_actionseq, log_cmdtype, log_cmdargs) 461s values 461s (c_local_node, pg_catalog.txid_current(), 461s nextval('public.sl_action_seq'), 'S', c_cmdargs); 461s execute p_statement; 461s return currval('public.sl_action_seq'); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.ddlCapture (p_statement text, p_nodes text) is 461s 'Capture an SQL statement (usually DDL) that is to be literally replayed on subscribers'; 461s COMMENT 461s drop function if exists public.ddlScript_complete (int4, text, int4); 461s DROP FUNCTION 461s create or replace function public.ddlScript_complete (p_nodes text) 461s returns bigint 461s as $$ 461s declare 461s c_local_node integer; 461s c_found_origin boolean; 461s c_node text; 461s c_cmdargs text[]; 461s begin 461s c_local_node := public.getLocalNodeId('_main'); 461s 461s c_cmdargs = '{}'::text[]; 461s if p_nodes is not null then 461s c_found_origin := 'f'; 461s -- p_nodes list needs to consist o a list of nodes that exist 461s -- and that include the current node ID 461s for c_node in select trim(node) from 461s pg_catalog.regexp_split_to_table(p_nodes, ',') as node loop 461s if not exists 461s (select 1 from public.sl_node 461s where no_id = (c_node::integer)) then 461s raise exception 'ddlcapture(%,%) - node % does not exist!', 461s p_statement, p_nodes, c_node; 461s end if; 461s 461s if c_local_node = (c_node::integer) then 461s c_found_origin := 't'; 461s end if; 461s 461s c_cmdargs = array_append(c_cmdargs, c_node); 461s end loop; 461s 461s if not c_found_origin then 461s raise exception 461s 'ddlScript_complete(%) - origin node % not included in ONLY ON list!', 461s p_nodes, c_local_node; 461s end if; 461s end if; 461s 461s perform public.ddlScript_complete_int(); 461s 461s insert into public.sl_log_script 461s (log_origin, log_txid, log_actionseq, log_cmdtype, log_cmdargs) 461s values 461s (c_local_node, pg_catalog.txid_current(), 461s nextval('public.sl_action_seq'), 's', c_cmdargs); 461s 461s return currval('public.sl_action_seq'); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.ddlScript_complete(p_nodes text) is 461s 'ddlScript_complete(set_id, script, only_on_node) 461s 461s After script has run on origin, this fixes up relnames and 461s log trigger arguments and inserts the "fire ddlScript_complete_int() 461s log row into sl_log_script.'; 461s COMMENT 461s drop function if exists public.ddlScript_complete_int(int4, int4); 461s DROP FUNCTION 461s create or replace function public.ddlScript_complete_int () 461s returns int4 461s as $$ 461s begin 461s perform public.updateRelname(); 461s perform public.repair_log_triggers(true); 461s return 0; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.ddlScript_complete_int() is 461s 'ddlScript_complete_int() 461s 461s Complete processing the DDL_SCRIPT event.'; 461s NOTICE: function public.ddlcapture(text,text) does not exist, skipping 461s NOTICE: function public.ddlscript_complete(int4,text,int4) does not exist, skipping 461s NOTICE: function public.ddlscript_complete_int(int4,int4) does not exist, skipping 461s COMMENT 461s create or replace function public.alterTableAddTriggers (p_tab_id int4) 461s returns int4 461s as $$ 461s declare 461s v_no_id int4; 461s v_tab_row record; 461s v_tab_fqname text; 461s v_tab_attkind text; 461s v_n int4; 461s v_trec record; 461s v_tgbad boolean; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Get our local node ID 461s -- ---- 461s v_no_id := public.getLocalNodeId('_main'); 461s 461s -- ---- 461s -- Get the sl_table row and the current origin of the table. 461s -- ---- 461s select T.tab_reloid, T.tab_set, T.tab_idxname, 461s S.set_origin, PGX.indexrelid, 461s public.slon_quote_brute(PGN.nspname) || '.' || 461s public.slon_quote_brute(PGC.relname) as tab_fqname 461s into v_tab_row 461s from public.sl_table T, public.sl_set S, 461s "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN, 461s "pg_catalog".pg_index PGX, "pg_catalog".pg_class PGXC 461s where T.tab_id = p_tab_id 461s and T.tab_set = S.set_id 461s and T.tab_reloid = PGC.oid 461s and PGC.relnamespace = PGN.oid 461s and PGX.indrelid = T.tab_reloid 461s and PGX.indexrelid = PGXC.oid 461s and PGXC.relname = T.tab_idxname 461s for update; 461s if not found then 461s raise exception 'Slony-I: alterTableAddTriggers(): Table with id % not found', p_tab_id; 461s end if; 461s v_tab_fqname = v_tab_row.tab_fqname; 461s 461s v_tab_attkind := public.determineAttKindUnique(v_tab_row.tab_fqname, 461s v_tab_row.tab_idxname); 461s 461s execute 'lock table ' || v_tab_fqname || ' in access exclusive mode'; 461s 461s -- ---- 461s -- Create the log and the deny access triggers 461s -- ---- 461s execute 'create trigger "_main_logtrigger"' || 461s ' after insert or update or delete on ' || 461s v_tab_fqname || ' for each row execute procedure public.logTrigger (' || 461s pg_catalog.quote_literal('_main') || ',' || 461s pg_catalog.quote_literal(p_tab_id::text) || ',' || 461s pg_catalog.quote_literal(v_tab_attkind) || ');'; 461s 461s execute 'create trigger "_main_denyaccess" ' || 461s 'before insert or update or delete on ' || 461s v_tab_fqname || ' for each row execute procedure ' || 461s 'public.denyAccess (' || pg_catalog.quote_literal('_main') || ');'; 461s 461s perform public.alterTableAddTruncateTrigger(v_tab_fqname, p_tab_id); 461s 461s perform public.alterTableConfigureTriggers (p_tab_id); 461s return p_tab_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.alterTableAddTriggers(p_tab_id int4) is 461s 'alterTableAddTriggers(tab_id) 461s 461s Adds the log and deny access triggers to a replicated table.'; 461s COMMENT 461s create or replace function public.alterTableDropTriggers (p_tab_id int4) 461s returns int4 461s as $$ 461s declare 461s v_no_id int4; 461s v_tab_row record; 461s v_tab_fqname text; 461s v_n int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Get our local node ID 461s -- ---- 461s v_no_id := public.getLocalNodeId('_main'); 461s 461s -- ---- 461s -- Get the sl_table row and the current tables origin. 461s -- ---- 461s select T.tab_reloid, T.tab_set, 461s S.set_origin, PGX.indexrelid, 461s public.slon_quote_brute(PGN.nspname) || '.' || 461s public.slon_quote_brute(PGC.relname) as tab_fqname 461s into v_tab_row 461s from public.sl_table T, public.sl_set S, 461s "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN, 461s "pg_catalog".pg_index PGX, "pg_catalog".pg_class PGXC 461s where T.tab_id = p_tab_id 461s and T.tab_set = S.set_id 461s and T.tab_reloid = PGC.oid 461s and PGC.relnamespace = PGN.oid 461s and PGX.indrelid = T.tab_reloid 461s and PGX.indexrelid = PGXC.oid 461s and PGXC.relname = T.tab_idxname 461s for update; 461s if not found then 461s raise exception 'Slony-I: alterTableDropTriggers(): Table with id % not found', p_tab_id; 461s end if; 461s v_tab_fqname = v_tab_row.tab_fqname; 461s 461s execute 'lock table ' || v_tab_fqname || ' in access exclusive mode'; 461s 461s -- ---- 461s -- Drop both triggers 461s -- ---- 461s execute 'drop trigger "_main_logtrigger" on ' || 461s v_tab_fqname; 461s 461s execute 'drop trigger "_main_denyaccess" on ' || 461s v_tab_fqname; 461s 461s perform public.alterTableDropTruncateTrigger(v_tab_fqname, p_tab_id); 461s 461s return p_tab_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.alterTableDropTriggers (p_tab_id int4) is 461s 'alterTableDropTriggers (tab_id) 461s 461s Remove the log and deny access triggers from a table.'; 461s COMMENT 461s create or replace function public.alterTableConfigureTriggers (p_tab_id int4) 461s returns int4 461s as $$ 461s declare 461s v_no_id int4; 461s v_tab_row record; 461s v_tab_fqname text; 461s v_n int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Get our local node ID 461s -- ---- 461s v_no_id := public.getLocalNodeId('_main'); 461s 461s -- ---- 461s -- Get the sl_table row and the current tables origin. 461s -- ---- 461s select T.tab_reloid, T.tab_set, 461s S.set_origin, PGX.indexrelid, 461s public.slon_quote_brute(PGN.nspname) || '.' || 461s public.slon_quote_brute(PGC.relname) as tab_fqname 461s into v_tab_row 461s from public.sl_table T, public.sl_set S, 461s "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN, 461s "pg_catalog".pg_index PGX, "pg_catalog".pg_class PGXC 461s where T.tab_id = p_tab_id 461s and T.tab_set = S.set_id 461s and T.tab_reloid = PGC.oid 461s and PGC.relnamespace = PGN.oid 461s and PGX.indrelid = T.tab_reloid 461s and PGX.indexrelid = PGXC.oid 461s and PGXC.relname = T.tab_idxname 461s for update; 461s if not found then 461s raise exception 'Slony-I: alterTableConfigureTriggers(): Table with id % not found', p_tab_id; 461s end if; 461s v_tab_fqname = v_tab_row.tab_fqname; 461s 461s -- ---- 461s -- Configuration depends on the origin of the table 461s -- ---- 461s if v_tab_row.set_origin = v_no_id then 461s -- ---- 461s -- On the origin the log trigger is configured like a default 461s -- user trigger and the deny access trigger is disabled. 461s -- ---- 461s execute 'alter table ' || v_tab_fqname || 461s ' enable trigger "_main_logtrigger"'; 461s execute 'alter table ' || v_tab_fqname || 461s ' disable trigger "_main_denyaccess"'; 461s perform public.alterTableConfigureTruncateTrigger(v_tab_fqname, 461s 'enable', 'disable'); 461s else 461s -- ---- 461s -- On a replica the log trigger is disabled and the 461s -- deny access trigger fires in origin session role. 461s -- ---- 461s execute 'alter table ' || v_tab_fqname || 461s ' disable trigger "_main_logtrigger"'; 461s execute 'alter table ' || v_tab_fqname || 461s ' enable trigger "_main_denyaccess"'; 461s perform public.alterTableConfigureTruncateTrigger(v_tab_fqname, 461s 'disable', 'enable'); 461s 461s end if; 461s 461s return p_tab_id; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.alterTableConfigureTriggers (p_tab_id int4) is 461s 'alterTableConfigureTriggers (tab_id) 461s 461s Set the enable/disable configuration for the replication triggers 461s according to the origin of the set.'; 461s COMMENT 461s create or replace function public.resubscribeNode (p_origin int4, 461s p_provider int4, p_receiver int4) 461s returns bigint 461s as $$ 461s declare 461s v_record record; 461s v_missing_sets text; 461s v_ev_seqno bigint; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- 461s -- Check that the receiver exists 461s -- 461s if not exists (select no_id from public.sl_node where no_id= 461s p_receiver) then 461s raise exception 'Slony-I: subscribeSet() receiver % does not exist' , p_receiver; 461s end if; 461s 461s -- 461s -- Check that the provider exists 461s -- 461s if not exists (select no_id from public.sl_node where no_id= 461s p_provider) then 461s raise exception 'Slony-I: subscribeSet() provider % does not exist' , p_provider; 461s end if; 461s 461s 461s -- ---- 461s -- Check that this is called on the origin node 461s -- ---- 461s if p_origin != public.getLocalNodeId('_main') then 461s raise exception 'Slony-I: subscribeSet() must be called on origin'; 461s end if; 461s 461s -- --- 461s -- Verify that the provider is either the origin or an active subscriber 461s -- Bug report #1362 461s -- --- 461s if p_origin <> p_provider then 461s for v_record in select sub1.sub_set from 461s public.sl_subscribe sub1 461s left outer join (public.sl_subscribe sub2 461s inner join 461s public.sl_set on ( 461s sl_set.set_id=sub2.sub_set 461s and sub2.sub_set=p_origin) 461s ) 461s ON ( sub1.sub_set = sub2.sub_set and 461s sub1.sub_receiver = p_provider and 461s sub1.sub_forward and sub1.sub_active 461s and sub2.sub_receiver=p_receiver) 461s 461s wheNOTICE: function public.subscribeset_int(int4,int4,int4,bool,bool) does not exist, skipping 461s NOTICE: function public.unsubscribeset(int4,int4,pg_catalog.bool) does not exist, skipping 461s re sub2.sub_set is null 461s loop 461s v_missing_sets=v_missing_sets || ' ' || v_record.sub_set; 461s end loop; 461s if v_missing_sets is not null then 461s raise exception 'Slony-I: subscribeSet(): provider % is not an active forwarding node for replication set %', p_sub_provider, v_missing_sets; 461s end if; 461s end if; 461s 461s for v_record in select * from 461s public.sl_subscribe, public.sl_set where 461s sub_set=set_id and 461s sub_receiver=p_receiver 461s and set_origin=p_origin 461s loop 461s -- ---- 461s -- Create the SUBSCRIBE_SET event 461s -- ---- 461s v_ev_seqno := public.createEvent('_main', 'SUBSCRIBE_SET', 461s v_record.sub_set::text, p_provider::text, p_receiver::text, 461s case v_record.sub_forward when true then 't' else 'f' end, 461s 'f' ); 461s 461s -- ---- 461s -- Call the internal procedure to store the subscription 461s -- ---- 461s perform public.subscribeSet_int(v_record.sub_set, 461s p_provider, 461s p_receiver, v_record.sub_forward, false); 461s end loop; 461s 461s return v_ev_seqno; 461s end; 461s $$ 461s language plpgsql; 461s CREATE FUNCTION 461s create or replace function public.subscribeSet (p_sub_set int4, p_sub_provider int4, p_sub_receiver int4, p_sub_forward bool, p_omit_copy bool) 461s returns bigint 461s as $$ 461s declare 461s v_set_origin int4; 461s v_ev_seqno int8; 461s v_ev_seqno2 int8; 461s v_rec record; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- 461s -- Check that the receiver exists 461s -- 461s if not exists (select no_id from public.sl_node where no_id= 461s p_sub_receiver) then 461s raise exception 'Slony-I: subscribeSet() receiver % does not exist' , p_sub_receiver; 461s end if; 461s 461s -- 461s -- Check that the provider exists 461s -- 461s if not exists (select no_id from public.sl_node where no_id= 461s p_sub_provider) then 461s raise exception 'Slony-I: subscribeSet() provider % does not exist' , p_sub_provider; 461s end if; 461s 461s -- ---- 461s -- Check that the origin and provider of the set are remote 461s -- ---- 461s select set_origin into v_set_origin 461s from public.sl_set 461s where set_id = p_sub_set; 461s if not found then 461s raise exception 'Slony-I: subscribeSet(): set % not found', p_sub_set; 461s end if; 461s if v_set_origin = p_sub_receiver then 461s raise exception 461s 'Slony-I: subscribeSet(): set origin and receiver cannot be identical'; 461s end if; 461s if p_sub_receiver = p_sub_provider then 461s raise exception 461s 'Slony-I: subscribeSet(): set provider and receiver cannot be identical'; 461s end if; 461s -- ---- 461s -- Check that this is called on the origin node 461s -- ---- 461s if v_set_origin != public.getLocalNodeId('_main') then 461s raise exception 'Slony-I: subscribeSet() must be called on origin'; 461s end if; 461s 461s -- --- 461s -- Verify that the provider is either the origin or an active subscriber 461s -- Bug report #1362 461s -- --- 461s if v_set_origin <> p_sub_provider then 461s if not exists (select 1 from public.sl_subscribe 461s where sub_set = p_sub_set and 461s sub_receiver = p_sub_provider and 461s sub_forward and sub_active) then 461s raise exception 'Slony-I: subscribeSet(): provider % is not an active forwarding node for replication set %', p_sub_provider, p_sub_set; 461s end if; 461s end if; 461s 461s -- --- 461s -- Enforce that all sets from one origin are subscribed 461s -- using the same data provider per receiver. 461s -- ---- 461s if not exists (select 1 from public.sl_subscribe 461s where sub_set = p_sub_set and sub_receiver = p_sub_receiver) then 461s -- 461s -- New subscription - error out if we have any other subscription 461s -- from that origin with a different data provider. 461s -- 461s for v_rec in select sub_provider from public.sl_subscribe 461s join public.sl_set on set_id = sub_set 461s where set_origin = v_set_origin and sub_receiver = p_sub_receiver 461s loop 461s if v_rec.sub_provider <> p_sub_provider then 461s raise exception 'Slony-I: subscribeSet(): wrong provider % - existing subscription from origin % users provider %', 461s p_sub_provider, v_set_origin, v_rec.sub_provider; 461s end if; 461s end loop; 461s else 461s -- 461s -- Existing subscription - in case the data provider changes and 461s -- there are other subscriptions, warn here. subscribeSet_int() 461s -- will currently change the data provider forNOTICE: function public.updaterelname(int4,int4) does not exist, skipping 461s NOTICE: function public.updatereloid(int4,int4) does not exist, skipping 461s those sets as well. 461s -- 461s for v_rec in select set_id, sub_provider from public.sl_subscribe 461s join public.sl_set on set_id = sub_set 461s where set_origin = v_set_origin and sub_receiver = p_sub_receiver 461s and set_id <> p_sub_set 461s loop 461s if v_rec.sub_provider <> p_sub_provider then 461s raise exception 'Slony-I: subscribeSet(): also data provider for set % use resubscribe instead', 461s v_rec.set_id; 461s end if; 461s end loop; 461s end if; 461s 461s -- ---- 461s -- Create the SUBSCRIBE_SET event 461s -- ---- 461s v_ev_seqno := public.createEvent('_main', 'SUBSCRIBE_SET', 461s p_sub_set::text, p_sub_provider::text, p_sub_receiver::text, 461s case p_sub_forward when true then 't' else 'f' end, 461s case p_omit_copy when true then 't' else 'f' end 461s ); 461s 461s -- ---- 461s -- Call the internal procedure to store the subscription 461s -- ---- 461s v_ev_seqno2:=public.subscribeSet_int(p_sub_set, p_sub_provider, 461s p_sub_receiver, p_sub_forward, p_omit_copy); 461s 461s if v_ev_seqno2 is not null then 461s v_ev_seqno:=v_ev_seqno2; 461s end if; 461s 461s return v_ev_seqno; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.subscribeSet (p_sub_set int4, p_sub_provider int4, p_sub_receiver int4, p_sub_forward bool, p_omit_copy bool) is 461s 'subscribeSet (sub_set, sub_provider, sub_receiver, sub_forward, omit_copy) 461s 461s Makes sure that the receiver is not the provider, then stores the 461s subscription, and publishes the SUBSCRIBE_SET event to other nodes. 461s 461s If omit_copy is true, then no data copy will be done. 461s '; 461s COMMENT 461s DROP FUNCTION IF EXISTS public.subscribeSet_int(int4,int4,int4,bool,bool); 461s DROP FUNCTION 461s create or replace function public.subscribeSet_int (p_sub_set int4, p_sub_provider int4, p_sub_receiver int4, p_sub_forward bool, p_omit_copy bool) 461s returns int4 461s as $$ 461s declare 461s v_set_origin int4; 461s v_sub_row record; 461s v_seq_id bigint; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Lookup the set origin 461s -- ---- 461s select set_origin into v_set_origin 461s from public.sl_set 461s where set_id = p_sub_set; 461s if not found then 461s raise exception 'Slony-I: subscribeSet_int(): set % not found', p_sub_set; 461s end if; 461s 461s -- ---- 461s -- Provider change is only allowed for active sets 461s -- ---- 461s if p_sub_receiver = public.getLocalNodeId('_main') then 461s select sub_active into v_sub_row from public.sl_subscribe 461s where sub_set = p_sub_set 461s and sub_receiver = p_sub_receiver; 461s if found then 461s if not v_sub_row.sub_active then 461s raise exception 'Slony-I: subscribeSet_int(): set % is not active, cannot change provider', 461s p_sub_set; 461s end if; 461s end if; 461s end if; 461s 461s -- ---- 461s -- Try to change provider and/or forward for an existing subscription 461s -- ---- 461s update public.sl_subscribe 461s set sub_provider = p_sub_provider, 461s sub_forward = p_sub_forward 461s where sub_set = p_sub_set 461s and sub_receiver = p_sub_receiver; 461s if found then 461s 461s -- ---- 461s -- This is changing a subscriptoin. Make sure all sets from 461s -- this origin are subscribed using the same data provider. 461s -- For this we first check that the requested data provider 461s -- is subscribed to all the sets, the receiver is subscribed to. 461s -- ---- 461s for v_sub_row in select set_id from public.sl_set 461s join public.sl_subscribe on set_id = sub_set 461s where set_origin = v_set_origin 461s and sub_receiver = p_sub_receiver 461s and sub_set <> p_sub_set 461s loop 461s if not exists (select 1 from public.sl_subscribe 461s where sub_set = v_sub_row.set_id 461s and sub_receiver = p_sub_provider 461s and sub_active and sub_forward) 461s and not exists (select 1 from public.sl_set 461s where set_id = v_sub_row.set_id 461s and set_origin = p_sub_provider) 461s then 461s raise exception 'Slony-I: subscribeSet_int(): node % is not a forwarding subscriber for set %', 461s p_sub_provider, v_sub_row.set_id; 461s end if; 461s 461s -- ---- 461s -- New data provider offers this set as well, change that 461s -- subscription too. 461s -- ---- 461s update public.sl_subscribe 461s set sub_provider = p_sub_provider 461s where sub_set = v_sub_row.set_id 461s and sub_receiver = p_sub_receiver; 461s end loop; 461s 461s -- ---- 461s -- Rewrite sl_listen table 461s -- ---- 461s perform public.RebuildListenEntries(); 461s 461s return p_sub_set; 461s end if; 461s 461s -- ---- 461s -- Not found, insert a new one 461s -- ---- 461s if not exists (select true from public.sl_path 461s where pa_server = p_sub_provider 461s and pa_client = p_sub_receiver) 461s then 461s insert into public.sl_path 461s (pa_server, pa_client, pa_conninfo, pa_connretry) 461s values 461s (p_sub_provider, p_sub_receiver, 461s '', 10); 461s end if; 461s insert into public.sl_subscribe 461s (sub_set, sub_provider, sub_receiver, sub_forward, sub_active) 461s values (p_sub_set, p_sub_provider, p_sub_receiver, 461s p_sub_forward, false); 461s 461s -- ---- 461s -- If the set origin is here, then enable the subscription 461s -- ---- 461s if v_set_origin = public.getLocalNodeId('_main') then 461s select public.createEvent('_main', 'ENABLE_SUBSCRIPTION', 461s p_sub_set::text, p_sub_provider::text, p_sub_receiver::text, 461s case p_sub_forward when true then 't' else 'f' end, 461s case p_omit_copy when true then 't' else 'f' end 461s ) into v_seq_id; 461s perform public.enableSubscription(p_sub_set, 461s p_sub_provider, p_sub_receiver); 461s end if; 461s 461s -- ---- 461s -- Rewrite sl_listen table 461s -- ---- 461s perform public.RebuildListenEntries(); 461s 461s return p_sub_set; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.subscribeSet_int (p_sub_set int4, p_sub_provider int4, p_sub_receiver int4, p_sub_forward bool, p_omit_copy bool) is 461s 'subscribeSet_int (sub_set, sub_provider, sub_receiver, sub_forward, omit_copy) 461s 461s Internal actions for subscribing receiver sub_receiver to subscription 461s set sub_set.'; 461s COMMENT 461s drop function IF EXISTS public.unsubscribeSet(int4,int4,boolean); 461s DROP FUNCTION 461s create or replace function public.unsubscribeSet (p_sub_set int4, p_sub_receiver int4,p_force boolean) 461s returns bigint 461s as $$ 461s declare 461s v_tab_row record; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- Check that this is called on the receiver node 461s -- ---- 461s if p_sub_receiver != public.getLocalNodeId('_main') then 461s raise exception 'Slony-I: unsubscribeSet() must be called on receiver'; 461s end if; 461s 461s 461s 461s -- ---- 461s -- Check that this does not break any chains 461s -- ---- 461s if p_force=false and exists (select true from public.sl_subscribe 461s where sub_set = p_sub_set 461s and sub_provider = p_sub_receiver) 461s then 461s raise exception 'Slony-I: Cannot unsubscribe set % while being provider', 461s p_sub_set; 461s end if; 461s 461s if exists (select true from public.sl_subscribe 461s where sub_set = p_sub_set 461s and sub_provider = p_sub_receiver) 461s then 461s --delete the receivers of this provider. 461s --unsubscribeSet_int() will generate the event 461s --when it runs on the receiver. 461s delete from public.sl_subscribe 461s where sub_set=p_sub_set 461s and sub_provider=p_sub_receiver; 461s end if; 461s 461s -- ---- 461s -- Remove the replication triggers. 461s -- ---- 461s for v_tab_row in select tab_id from public.sl_table 461s where tab_set = p_sub_set 461s order by tab_id 461s loop 461s perform public.alterTableDropTriggers(v_tab_row.tab_id); 461s end loop; 461s 461s -- ---- 461s -- Remove the setsync status. This will also cause the 461s -- worker thread to ignore the set and stop replicating 461s -- right now. 461s -- ---- 461s delete from public.sl_setsync 461s where ssy_setid = p_sub_set; 461s 461s -- ---- 461s -- Remove all sl_table and sl_sequence entries for this set. 461s -- Should we ever subscribe again, the initial data 461s -- copy process will create new ones. 461s -- ---- 461s delete from public.sl_table 461s where tab_set = p_sub_set; 461s delete from public.sl_sequence 461s where seq_set = p_sub_set; 461s 461s -- ---- 461s -- Call the internal procedure to drop the subscription 461s -- ---- 461s perform public.unsubscribeSet_int(p_sub_set, p_sub_receiver); 461s 461s -- Rewrite sl_listen table 461s perform public.RebuildListenEntries(); 461s 461s -- ---- 461s -- Create the UNSUBSCRIBE_SET event 461s -- ---- 461s return public.createEvent('_main', 'UNSUBSCRIBE_SET', 461s p_sub_set::text, p_sub_receiver::text); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.unsubscribeSet (p_sub_set int4, p_sub_receiver int4,force boolean) is 461s 'unsubscribeSet (sub_set, sub_receiver,force) 461s 461s Unsubscribe node sub_receiver from subscription set sub_set. This is 461s invoked on the receiver node. It verifies that this does not break 461s any chains (e.g. - where sub_receiver is a provider for another node), 461s then restores tables, drops Slony-specific keys, drops table entries 461s for the set, drops the subscription, and generates an UNSUBSCRIBE_SET 461s node to publish that the node is being dropped.'; 461s COMMENT 461s create or replace function public.unsubscribeSet_int (p_sub_set int4, p_sub_receiver int4) 461s returns int4 461s as $$ 461s declare 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- All the real work is done before event generation on the 461s -- subscriber. 461s -- ---- 461s 461s --if this event unsubscribes the provider of this node 461s --then this node should unsubscribe itself from the set as well. 461s 461s if exists (select true from 461s public.sl_subscribe where 461s sub_set=p_sub_set and sub_provider=p_sub_receiver 461s and sub_receiver=public.getLocalNodeId('_main')) 461s then 461s perform public.unsubscribeSet(p_sub_set,public.getLocalNodeId('_main'),true); 461s end if; 461s 461s 461s delete from public.sl_subscribe 461s where sub_set = p_sub_set 461s and sub_receiver = p_sub_receiver; 461s 461s -- Rewrite sl_listen table 461s perform public.RebuildListenEntries(); 461s 461s return p_sub_set; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.unsubscribeSet_int (p_sub_set int4, p_sub_receiver int4) is 461s 'unsubscribeSet_int (sub_set, sub_receiver) 461s 461s All the REAL work of removing the subscriber is done before the event 461s is generated, so this function just has to drop the references to the 461s subscription in sl_subscribe.'; 461s COMMENT 461s create or replace function public.enableSubscription (p_sub_set int4, p_sub_provider int4, p_sub_receiver int4) 461s returns int4 461s as $$ 461s begin 461s return public.enableSubscription_int (p_sub_set, 461s p_sub_provider, p_sub_receiver); 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.enableSubscription (p_sub_set int4, p_sub_provider int4, p_sub_receiver int4) is 461s 'enableSubscription (sub_set, sub_provider, sub_receiver) 461s 461s Indicates that sub_receiver intends subscribing to set sub_set from 461s sub_provider. Work is all done by the internal function 461s enableSubscription_int (sub_set, sub_provider, sub_receiver).'; 461s COMMENT 461s create or replace function public.enableSubscription_int (p_sub_set int4, p_sub_provider int4, p_sub_receiver int4) 461s returns int4 461s as $$ 461s declare 461s v_n int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- ---- 461s -- The real work is done in the replication engine. All 461s -- we have to do here is remembering that it happened. 461s -- ---- 461s 461s -- ---- 461s -- Well, not only ... we might be missing an important event here 461s -- ---- 461s if not exists (select true from public.sl_path 461s where pa_server = p_sub_provider 461s and pa_client = p_sub_receiver) 461s then 461s insert into public.sl_path 461s (pa_server, pa_client, pa_conninfo, pa_connretry) 461s values 461s (p_sub_provider, p_sub_receiver, 461s '', 10); 461s end if; 461s 461s update public.sl_subscribe 461s set sub_active = 't' 461s where sub_set = p_sub_set 461s and sub_receiver = p_sub_receiver; 461s get diagnostics v_n = row_count; 461s if v_n = 0 then 461s insert into public.sl_subscribe 461s (sub_set, sub_provider, sub_receiver, 461s sub_forward, sub_active) 461s values 461s (p_sub_set, p_sub_provider, p_sub_receiver, 461s false, true); 461s end if; 461s 461s -- Rewrite sl_listen table 461s perform public.RebuildListenEntries(); 461s 461s return p_sub_set; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.enableSubscription_int (p_sub_set int4, p_sub_provider int4, p_sub_receiver int4) is 461s 'enableSubscription_int (sub_set, sub_provider, sub_receiver) 461s 461s Internal function to enable subscription of node sub_receiver to set 461s sub_set via node sub_provider. 461s 461s slon does most of the work; all we need do here is to remember that it 461s happened. The function updates sl_subscribe, indicating that the 461s subscription has become active.'; 461s COMMENT 461s create or replace function public.forwardConfirm (p_con_origin int4, p_con_received int4, p_con_seqno int8, p_con_timestamp timestamp) 461s returns bigint 461s as $$ 461s declare 461s v_max_seqno bigint; 461s begin 461s select into v_max_seqno coalesce(max(con_seqno), 0) 461s from public.sl_confirm 461s where con_origin = p_con_origin 461s and con_received = p_con_received; 461s if v_max_seqno < p_con_seqno then 461s insert into public.sl_confirm 461s (con_origin, con_received, con_seqno, con_timestamp) 461s values (p_con_origin, p_con_received, p_con_seqno, 461s p_con_timestamp); 461s v_max_seqno = p_con_seqno; 461s end if; 461s 461s return v_max_seqno; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.forwardConfirm (p_con_origin int4, p_con_received int4, p_con_seqno int8, p_con_timestamp timestamp) is 461s 'forwardConfirm (p_con_origin, p_con_received, p_con_seqno, p_con_timestamp) 461s 461s Confirms (recorded in sl_confirm) that items from p_con_origin up to 461s p_con_seqno have been received by node p_con_received as of 461s p_con_timestamp, and raises an event to forward this confirmation.'; 461s COMMENT 461s create or replace function public.cleanupEvent (p_interval interval) 461s returns int4 461s as $$ 461s declare 461s v_max_row record; 461s v_min_row record; 461s v_max_sync int8; 461s v_origin int8; 461s v_seqno int8; 461s v_xmin bigint; 461s v_rc int8; 461s begin 461s -- ---- 461s -- First remove all confirmations where origin/receiver no longer exist 461s -- ---- 461s delete from public.sl_confirm 461s where con_origin not in (select no_id from public.sl_node); 461s delete from public.sl_confirm 461s where con_received not in (select no_id from public.sl_node); 461s -- ---- 461s -- Next remove all but the oldest confirm row per origin,receiver pair. 461s -- Ignore confirmations that are younger than 10 minutes. We currently 461s -- have an not confirmed suspicion that a possibly lost transaction due 461s -- to a server crash might have been visible to another session, and 461s -- that this led to log data that is needed again got removed. 461s -- ---- 461s for v_max_row in select con_origin, con_received, max(con_seqno) as con_seqno 461s from public.sl_confirm 461s where con_timestamp < (CURRENT_TIMESTAMP - p_interval) 461s group by con_origin, con_received 461s loop 461s delete from public.sl_confirm 461s where con_origin = v_max_row.con_origin 461s and con_received = v_max_row.con_received 461s and con_seqno < v_max_row.con_seqno; 461s end loop; 461s 461s -- ---- 461s -- Then remove all events that are confirmed by all nodes in the 461s -- whole cluster up to the last SYNC 461s -- ---- 461s for v_min_row in select con_origin, min(con_seqno) as con_seqno 461s from public.sl_confirm 461s group by con_origin 461s loop 461s select coalesce(max(ev_seqno), 0) into v_max_sync 461s from public.sl_event 461s where ev_origin = v_min_row.con_origin 461s and ev_seqno <= v_min_row.con_seqno 461s and ev_type = 'SYNC'; 461s if v_max_sync > 0 then 461s delete from public.sl_event 461s where ev_origin = v_min_row.con_origin 461s and ev_seqno < v_max_sync; 461s end if; 461s end loop; 461s 461s -- ---- 461s -- If cluster has only one node, then remove all events up to 461s -- the last SYNC - Bug #1538 461s -- http://gborg.postgresql.org/project/slony1/bugs/bugupdate.php?1538 461s -- ---- 461s 461s select * into v_min_row from public.sl_node where 461s no_id <> public.getLocalNodeId('_main') limit 1; 461s if not found then 461s select ev_origin, ev_seqno into v_min_row from public.sl_event 461s where ev_origin = public.getLocalNodeId('_main') 461s order by ev_origin desc, ev_seqno desc limit 1; 461s raise notice 'Slony-I: cleanupEvent(): Single node - deleting events < %', v_min_row.ev_seqno; 461s delete from public.sl_event 461s where 461s ev_origin = v_min_row.ev_origin and 461s ev_seqno < v_min_row.ev_seqno; 461s 461s end if; 461s 461s if exists (select * from "pg_catalog".pg_class c, "pg_catalog".pg_namespace n, "pg_catalog".pg_attribute a where c.relname = 'sl_seqlog' and n.oid = c.relnamespace and a.attrelid = c.oid and a.attname = 'oid') then 461s execute 'alter table public.sl_seqlog set without oids;'; 461s end if; 461s -- ---- 461s -- Also remove stale entries from the nodelock table. 461s -- ---- 461s perform public.cleanupNodelock(); 461s 461s -- ---- 461s -- Find the eldest event left, for each origin 461s -- ---- 461s for v_origin, v_seqno, v_xmin in 461s select ev_origin, ev_seqno, "pg_catalog".txid_snapshot_xmin(ev_snapshot) from public.sl_event 461s where (ev_origin, ev_seqno) in (select ev_origin, min(ev_seqno) from public.sl_event where ev_type = 'SYNC' group by ev_origin) 461s loop 461s delete from public.sl_seqlog where seql_origin = v_origin and seql_ev_seqno < v_seqno; 461s delete from public.sl_log_script where log_origin = v_origin and log_txid < v_xmin; 461s end loop; 461s 461s v_rc := public.logswitch_finish(); 461s if v_rc = 0 then -- no switch in progress 461s perform public.logswitch_start(); 461s end if; 461s 461s return 0; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.cleanupEvent (p_interval interval) is 461s 'cleaning old data out of sl_confirm, sl_event. Removes all but the 461s last sl_confirm row per (origin,receiver), and then removes all events 461s that are confirmed by all nodes in the whole cluster up to the last 461s SYNC.'; 461s COMMENT 461s create or replace function public.determineIdxnameUnique(p_tab_fqname text, p_idx_name name) returns name 461s as $$ 461s declare 461s v_tab_fqname_quoted text default ''; 461s v_idxrow record; 461s begin 461s v_tab_fqname_quoted := public.slon_quote_input(p_tab_fqname); 461s -- 461s -- Ensure that the table exists 461s -- 461s if (select PGC.relname 461s from "pg_catalog".pg_class PGC, 461s "pg_catalog".pg_namespace PGN 461s where public.slon_quote_brute(PGN.nspname) || '.' || 461s public.slon_quote_brute(PGC.relname) = v_tab_fqname_quoted 461s and PGN.oid = PGC.relnamespace) is null then 461s raise exception 'Slony-I: determineIdxnameUnique(): table % not found', v_tab_fqname_quoted; 461s end if; 461s 461s -- 461s -- Lookup the tables primary key or the specified unique index 461s -- 461s if p_idx_name isnull then 461s select PGXC.relname 461s into v_idxrow 461s from "pg_catalog".pg_class PGC, 461s "pg_catalog".pg_namespace PGN, 461s "pg_catalog".pg_index PGX, 461s "pg_catalog".pg_class PGXC 461s where public.slon_quote_brute(PGN.nspname) || '.' || 461s public.slon_quote_brute(PGC.relname) = v_tab_fqname_quoted 461s and PGN.oid = PGC.relnamespace 461s and PGX.indrelid = PGC.oid 461s and PGX.indexrelid = PGXC.oid 461s and PGX.indisprimary; 461s if not found then 461s raise exception 'Slony-I: table % has no primary key', 461s v_tab_fqname_quoted; 461s end if; 461s else 461s select PGXC.relname 461s into v_idxrow 461s from "pg_catalog".pg_class PGC, 461s "pg_catalog".pg_namespace PGN, 461s "pg_catalog".pg_index PGX, 461s "pg_catalog".pg_class PGXC 461s where public.slon_quote_brute(PGN.nspname) || '.' || 461s public.slon_quote_brute(PGC.relname) = v_tab_fqname_quoted 461s and PGN.oid = PGC.relnamespace 461s and PGX.indrelid = PGC.oid 461s and PGX.indexrelid = PGXC.oid 461s and PGX.indisunique 461s and public.slon_quote_brute(PGXC.relname) = public.slon_quote_input(p_idx_name); 461s if not found then 461s raise exception 'Slony-I: table % has no unique index %', 461s v_tab_fqname_quoted, p_idx_name; 461s end if; 461s end if; 461s 461s -- 461s -- Return the found index name 461s -- 461s return v_idxrow.relname; 461s end; 461s $$ language plpgsql called on null input; 461s CREATE FUNCTION 461s comment on function public.determineIdxnameUnique(p_tab_fqname text, p_idx_name name) is 461s 'FUNCTION determineIdxnameUnique (tab_fqname, indexname) 461s 461s Given a tablename, tab_fqname, check that the unique index, indexname, 461s exists or return the primary key index name for the table. If there 461s is no unique index, it raises an exception.'; 461s COMMENT 461s create or replace function public.determineAttkindUnique(p_tab_fqname text, p_idx_name name) returns text 461s as $$ 461s declare 461s v_tab_fqname_quoted text default ''; 461s v_idx_name_quoted text; 461s v_idxrow record; 461s v_attrow record; 461s v_i integer; 461s v_attno int2; 461s v_attkind text default ''; 461s v_attfound bool; 461s begin 461s v_tab_fqname_quoted := public.slon_quote_input(p_tab_fqname); 461s v_idx_name_quoted := public.slon_quote_brute(p_idx_name); 461s -- 461s -- Ensure that the table exists 461s -- 461s if (select PGC.relname 461s from "pg_catalog".pg_class PGC, 461s "pg_catalog".pg_namespace PGN 461s where public.slon_quote_brute(PGN.nspname) || '.' || 461s public.slon_quote_brute(PGC.relname) = v_tab_fqname_quoted 461s and PGN.oid = PGC.relnamespace) is null then 461s raise exception 'Slony-I: table % not found', v_tab_fqname_quoted; 461s end if; 461s 461s -- 461s -- Lookup the tables primary key or the specified unique index 461s -- 461s if p_idx_name isnull then 461s raise exception 'Slony-I: index name must be specified'; 461s else 461s select PGXC.relname, PGX.indexrelid, PGX.indkey 461s into v_idxrow 461s from "pg_catalog".pg_class PGC, 461s "pg_catalog".pg_namespace PGN, 461s "pg_catalog".pg_index PGX, 461s "pg_catalog".pg_class PGXC 461s where public.slon_quote_brute(PGN.nspname) || '.' || 461s public.slon_quote_brute(PGC.relname) = v_tab_fqname_quoted 461s and PGN.oid = PGC.relnamespace 461s and PGX.indrelid = PGC.oid 461s and PGX.indexrelid = PGXC.oid 461s and PGX.indisunique 461s and public.slon_quote_brute(PGXC.relname) = v_idx_name_quoted; 461s if not found then 461s raise exception 'Slony-I: table % has no unique index %', 461s v_tab_fqname_quoted, v_idx_name_quoted; 461s end if; 461s end if; 461s 461s -- 461s -- Loop over the tables attributes and check if they are 461s -- index attributes. If so, add a "k" to the return value, 461s -- otherwise add a "v". 461s -- 461s for v_attrow in select PGA.attnum, PGA.attname 461s from "pg_catalog".pg_class PGC, 461s "pg_catalog".pg_namespace PGN, 461s "pg_catalog".pg_attribute PGA 461s where public.slon_quote_brute(PGN.nspname) || '.' || 461s public.slon_quote_brute(PGC.relname) = v_tab_fqname_quoted 461s and PGN.oid = PGC.relnamespace 461s and PGA.attrelid = PGC.oid 461s and not PGA.attisdropped 461s and PGA.attnum > 0 461s order by attnum 461s loop 461s v_attfound = 'f'; 461s 461s v_i := 0; 461s loop 461s select indkey[v_i] into v_attno from "pg_catalog".pg_index 461s where indexrelid = v_idxrow.indexrelid; 461s if v_attno isnull or v_attno = 0 then 461s exit; 461s end if; 461s if v_attrow.attnum = v_attno then 461s v_attfound = 't'; 461s exit; 461s end if; 461s v_i := v_i + 1; 461s end loop; 461s 461s if v_attfound then 461s v_attkind := v_attkind || 'k'; 461s else 461s v_attkind := v_attkind || 'v'; 461s end if; 461s end loop; 461s 461s -- Strip off trailing v characters as they are not needed by the logtrigger 461s v_attkind := pg_catalog.rtrim(v_attkind, 'v'); 461s 461s -- 461s -- Return the resulting attkind 461s -- 461s return v_attkind; 461s end; 461s $$ language plpgsql called on null input; 461s CREATE FUNCTION 461s comment on function public.determineAttkindUnique(p_tab_fqname text, p_idx_name name) is 461s 'determineAttKindUnique (tab_fqname, indexname) 461s 461s Given a tablename, return the Slony-I specific attkind (used for the 461s log trigger) of the table. Use the specified unique index or the 461s primary key (if indexname is NULL).'; 461s COMMENT 461s create or replace function public.RebuildListenEntries() 461s returns int 461s as $$ 461s declare 461s v_row record; 461s v_cnt integer; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s -- First remove the entire configuration 461s delete from public.sl_listen; 461s 461s -- Second populate the sl_listen configuration with a full 461s -- network of all possible paths. 461s insert into public.sl_listen 461s (li_origin, li_provider, li_receiver) 461s select pa_server, pa_server, pa_client from public.sl_path; 461s while true loop 461s insert into public.sl_listen 461s (li_origin, li_provider, li_receiver) 461s select distinct li_origin, pa_server, pa_client 461s from public.sl_listen, public.sl_path 461s where li_receiver = pa_server 461s and li_origin <> pa_client 461s and pa_conninfo<>'' 461s except 461s select li_origin, li_provider, li_receiver 461s from public.sl_listen; 461s 461s if not found then 461s exit; 461s end if; 461s end loop; 461s 461s -- We now replace specific event-origin,receiver combinations 461s -- with a configuration that tries to avoid events arriving at 461s -- a node before the data provider actually has the data ready. 461s 461s -- Loop over every possible pair of receiver and event origin 461s for v_row in select N1.no_id as receiver, N2.no_id as origin, 461s N2.no_failed as failed 461s from public.sl_node as N1, public.sl_node as N2 461s where N1.no_id <> N2.no_id 461s loop 461s -- 1st choice: 461s -- If we use the event origin as a data provider for any 461s -- set that originates on that very node, we are a direct 461s -- subscriber to that origin and listen there only. 461s if exists (select true from public.sl_set, public.sl_subscribe , public.sl_node p 461s where set_origin = v_row.origin 461s and sub_set = set_id 461s and sub_provider = v_row.origin 461s and sub_receiver = v_row.receiver 461s and sub_active 461s and p.no_active 461s and p.no_id=sub_provider 461s ) 461s then 461s delete from public.sl_listen 461s where li_origin = v_row.origin 461s and li_receiver = v_row.receiver; 461s insert into public.sl_listen (li_origin, li_provider, li_receiver) 461s values (v_row.origin, v_row.origin, v_row.receiver); 461s 461s -- 2nd choice: 461s -- If we are subscribed to any set originating on this 461s -- event origin, we want to listen on all data providers 461s -- we use for this origin. We are a cascaded subscriber 461s -- for sets from this node. 461s else 461s if exists (select true from public.sl_set, public.sl_subscribe, 461s public.sl_node provider 461s where set_origin = v_row.origin 461s and sub_set = set_id 461s and sub_provider=provider.no_id 461s and provider.no_failed = false 461s and sub_receiver = v_row.receiver 461s and sub_active) 461s then 461s delete from public.sl_listen 461s where li_origin = v_row.origin 461s and li_receiver = v_row.receiver; 461s insert into public.sl_listen (li_origin, li_provider, li_receiver) 461s select distinct set_origin, sub_provider, v_row.receiver 461s from public.sl_set, public.sl_subscribe 461s where set_origin = v_row.origin 461s and sub_set = set_id 461s and sub_receiver = v_row.receiver 461s and sub_active; 461s end if; 461s end if; 461s 461s if v_row.failed then 461s 461s --for every failed node we delete all sl_listen entries 461s --except via providers (listed in sl_subscribe) 461s --or failover candidates (sl_failover_targets) 461s --we do this to prevent a non-failover candidate 461s --that is more ahead of the failover candidate from 461s --sending events to the failover candidate that 461s --are 'too far ahead' 461s 461s --if the failed node is not an origin for any 461s --node then we don't delete all listen paths 461s --for events from it. Instead we leave 461s --the listen network alone. 461s 461s select count(*) into v_cnt from public.sl_subscribe sub, 461s public.sl_set s 461s where s.set_origin=v_row.origin and s.set_id=sub.sub_set; 461s if v_cnt > 0 then 461s delete from public.sl_listen where 461s li_origin=v_row.origin and 461s li_receiver=v_row.receiver 461s and li_provider not in 461s (select sub_provider from 461s public.sl_subscribe, 461s public.sl_set where 461s sub_set=set_id 461s and set_origin=v_row.origin); 461s end if; 461s end if; 461s -- insert into public.sl_listen 461s -- (li_origin,li_provider,li_receiver) 461s -- SELECT v_row.origin, pa_server 461s -- ,v_row.receiver 461s -- FROM public.sl_path where 461s -- pa_client=v_row.receiver 461s -- and (v_row.origin,pa_server,v_row.receiver) not in 461s -- (select li_origin,li_provider,li_receiver 461s -- from public.sl_listen); 461s -- end if; 461s end loop ; 461s 461s return null ; 461s end ; 461s $$ language 'plpgsql'; 461s CREATE FUNCTION 461s comment on function public.RebuildListenEntries() is 461s 'RebuildListenEntries() 461s 461s Invoked by various subscription and path modifying functions, this 461s rewrites the sl_listen entries, adding in all the ones required to 461s allow communications between nodes in the Slony-I cluster.'; 461s COMMENT 461s create or replace function public.generate_sync_event(p_interval interval) 461s returns int4 461s as $$ 461s declare 461s v_node_row record; 461s 461s BEGIN 461s select 1 into v_node_row from public.sl_event 461s where ev_type = 'SYNC' and ev_origin = public.getLocalNodeId('_main') 461s and ev_timestamp > now() - p_interval limit 1; 461s if not found then 461s -- If there has been no SYNC in the last interval, then push one 461s perform public.createEvent('_main', 'SYNC', NULL); 461s return 1; 461s else 461s return 0; 461s end if; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.generate_sync_event(p_interval interval) is 461s 'Generate a sync event if there has not been one in the requested interval, and this is a provider node.'; 461s COMMENT 461s drop function if exists public.updateRelname(int4, int4); 461s DROP FUNCTION 461s create or replace function public.updateRelname () 461s returns int4 461s as $$ 461s declare 461s v_no_id int4; 461s v_set_origin int4; 461s begin 461s -- ---- 461s -- Grab the central configuration lock 461s -- ---- 461s lock table public.sl_config_lock; 461s 461s update public.sl_table set 461s tab_relname = PGC.relname, tab_nspname = PGN.nspname 461s from pg_catalog.pg_class PGC, pg_catalog.pg_namespace PGN 461s where public.sl_table.tab_reloid = PGC.oid 461s and PGC.relnamespace = PGN.oid and 461s (tab_relname <> PGC.relname or tab_nspname <> PGN.nspname); 461s update public.sl_sequence set 461s seq_relname = PGC.relname, seq_nspname = PGN.nspname 461s from pg_catalog.pg_class PGC, pg_catalog.pg_namespace PGN 461s where public.sl_sequence.seq_reloid = PGC.oid 461s and PGC.relnamespace = PGN.oid and 461s (seq_relname <> PGC.relname or seq_nspname <> PGN.nspname); 461s return 0; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.updateRelname() is 461s 'updateRelname()'; 461s COMMENT 461s drop function if exists public.updateReloid (int4, int4); 461s DROP FUNCTION 461s create or replace function public.updateReloid (p_set_id int4, p_only_on_node int4) 461s returns bigint 461s as $$ 461s declare 461s v_no_id int4; 461s v_set_origin int4; 461s prec record; 461s begin 461s -- ---- 461s -- Check that we either are the set origin or a current 461s -- subscriber of the set. 461s -- ---- 461s v_no_id := public.getLocalNodeId('_main'); 461s select set_origin into v_set_origin 461s from public.sl_set 461s where set_id = p_set_id 461s for update; 461s if not found then 461s raise exception 'Slony-I: set % not found', p_set_id; 461s end if; 461s if v_set_origin <> v_no_id 461s and not exists (select 1 from public.sl_subscribe 461s where sub_set = p_set_id 461s and sub_receiver = v_no_id) 461s then 461s return 0; 461s end if; 461s 461s -- ---- 461s -- If execution on only one node is requested, check that 461s -- we are that node. 461s -- ---- 461s if p_only_on_node > 0 and p_only_on_node <> v_no_id then 461s return 0; 461s end if; 461s 461s -- Update OIDs for tables to values pulled from non-table objects in pg_class 461s -- This ensures that we won't have collisions when repairing the oids 461s for prec in select tab_id from public.sl_table loop 461s update public.sl_table set tab_reloid = (select oid from pg_class pc where relkind <> 'r' and not exists (select 1 from public.sl_table t2 where t2.tab_reloid = pc.oid) limit 1) 461s where tab_id = prec.tab_id; 461s end loop; 461s 461s for prec in select tab_id, tab_relname, tab_nspname from public.sl_table loop 461s update public.sl_table set 461s tab_reloid = (select PGC.oid 461s from pg_catalog.pg_class PGC, pg_catalog.pg_namespace PGN 461s where public.slon_quote_brute(PGC.relname) = public.slon_quote_brute(prec.tab_relname) 461s and PGC.relnamespace = PGN.oid 461s and public.slon_quote_brute(PGN.nspname) = public.slon_quote_brute(prec.tab_nspname)) 461s where tab_id = prec.tab_id; 461s end loop; 461s 461s for prec in select seq_id from public.sl_sequence loop 461s update public.sl_sequence set seq_reloid = (select oid from pg_class pc where relkind <> 'S' and not exists (select 1 from public.sl_sequence t2 where t2.seq_reloid = pc.oid) limit 1) 461s where seq_id = prec.seq_id; 461s end loop; 461s 461s for prec in select seq_id, seq_relname, seq_nspname from public.sl_sequence loop 461s update public.sl_sequence set 461s seq_reloid = (select PGC.oid 461s from pg_catalog.pg_class PGC, pg_catalog.pg_namespace PGN 461s where public.slon_quote_brute(PGC.relname) = public.slon_quote_brute(prec.seq_relname) 461s and PGC.relnamespace = PGN.oid 461s and public.slon_quote_brute(PGN.nspname) = public.slon_quote_brute(prec.seq_nspname)) 461s where seq_id = prec.seq_id; 461s end loop; 461s 461s return 1; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.updateReloid(p_set_id int4, p_only_on_node int4) is 461s 'updateReloid(set_id, only_on_node) 461s 461s Updates the respective reloids in sl_table and sl_seqeunce based on 461s their respective FQN'; 461s COMMENT 461s create or replace function public.logswitch_start() 461s returns int4 as $$ 461s DECLARE 461s v_current_status int4; 461s BEGIN 461s -- ---- 461s -- Get the current log status. 461s -- ---- 461s select last_value into v_current_status from public.sl_log_status; 461s 461s -- ---- 461s -- status = 0: sl_log_1 active, sl_log_2 clean 461s -- Initiate a switch to sl_log_2. 461s -- ---- 461s if v_current_status = 0 then 461s perform "pg_catalog".setval('public.sl_log_status', 3); 461s perform public.registry_set_timestamp( 461s 'logswitch.laststart', now()); 461s raise notice 'Slony-I: Logswitch to sl_log_2 initiated'; 461s return 2; 461s end if; 461s 461s -- ---- 461s -- status = 1: sl_log_2 active, sl_log_1 clean 461s -- Initiate a switch to sl_log_1. 461s -- ---- 461s if v_current_status = 1 then 461s perform "pg_catalog".setval('public.sl_log_status', 2); 461s perform public.registry_set_timestamp( 461s 'logswitch.laststart', now()); 461s raise notice 'Slony-I: Logswitch to sl_log_1 initiated'; 461s return 1; 461s end if; 461s 461s raise exception 'Previous logswitch still in progress'; 461s END; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.logswitch_start() is 461s 'logswitch_start() 461s 461s Initiate a log table switch if none is in progress'; 461s COMMENT 461s create or replace function public.logswitch_finish() 461s returns int4 as $$ 461s DECLARE 461s v_current_status int4; 461s v_dummy record; 461s v_origin int8; 461s v_seqno int8; 461s v_xmin bigint; 461s v_purgeable boolean; 461s BEGIN 461s -- ---- 461s -- Get the current log status. 461s -- ---- 461s select last_value into v_current_status from public.sl_log_status; 461s 461s -- ---- 461s -- status value 0 or 1 means that there is no log switch in progress 461s -- ---- 461s if v_current_status = 0 or v_current_status = 1 then 461s return 0; 461s end if; 461s 461s -- ---- 461s -- status = 2: sl_log_1 active, cleanup sl_log_2 461s -- ---- 461s if v_current_status = 2 then 461s v_purgeable := 'true'; 461s 461s -- ---- 461s -- Attempt to lock sl_log_2 in order to make sure there are no other transactions 461s -- currently writing to it. Exit if it is still in use. This prevents TRUNCATE from 461s -- blocking writers to sl_log_2 while it is waiting for a lock. It also prevents it 461s -- immediately truncating log data generated inside the transaction which was active 461s -- when logswitch_finish() was called (and was blocking TRUNCATE) as soon as that 461s -- transaction is committed. 461s -- ---- 461s begin 461s lock table public.sl_log_2 in access exclusive mode nowait; 461s exception when lock_not_available then 461s raise notice 'Slony-I: could not lock sl_log_2 - sl_log_2 not truncated'; 461s return -1; 461s end; 461s 461s -- ---- 461s -- The cleanup thread calls us after it did the delete and 461s -- vacuum of both log tables. If sl_log_2 is empty now, we 461s -- can truncate it and the log switch is done. 461s -- ---- 461s for v_origin, v_seqno, v_xmin in 461s select ev_origin, ev_seqno, "pg_catalog".txid_snapshot_xmin(ev_snapshot) from public.sl_event 461s where (ev_origin, ev_seqno) in (select ev_origin, min(ev_seqno) from public.sl_event where ev_type = 'SYNC' group by ev_origin) 461s loop 461s if exists (select 1 from public.sl_log_2 where log_origin = v_origin and log_txid >= v_xmin limit 1) then 461s v_purgeable := 'false'; 461s end if; 461s end loop; 461s if not v_purgeable then 461s -- ---- 461s -- Found a row ... log switch is still in progress. 461s -- ---- 461s raise notice 'Slony-I: log switch to sl_log_1 still in progress - sl_log_2 not truncated'; 461s return -1; 461s end if; 461s 461s raise notice 'Slony-I: log switch to sl_log_1 complete - truncate sl_log_2'; 461s truncate public.sl_log_2; 461s if exists (select * from "pg_catalog".pg_class c, "pg_catalog".pg_namespace n, "pg_catalog".pg_attribute a where c.relname = 'sl_log_2' and n.oid = c.relnamespace and a.attrelid = c.oid and a.attname = 'oid') then 461s execute 'alter table public.sl_log_2 set without oids;'; 461s end if; 461s perform "pg_catalog".setval('public.sl_log_status', 0); 461s -- Run addPartialLogIndices() to try to add indices to unused sl_log_? table 461s perform public.addPartialLogIndices(); 461s 461s return 1; 461s end if; 461s 461s -- ---- 461s -- status = 3: sl_log_2 active, cleanup sl_log_1 461s -- ---- 461s if v_current_status = 3 then 461s v_purgeable := 'true'; 461s 461s -- ---- 461s -- Attempt to lock sl_log_1 in order to make sure there are no other transactions 461s -- currently writing to it. Exit if it is still in use. This prevents TRUNCATE from 461s -- blocking writes to sl_log_1 while it is waiting for a lock. It also prevents it 461s -- immediately truncating log data generated inside the transaction which was active 461s -- when logswitch_finish() was called (and was blocking TRUNCATE) as soon as that 461s -- transaction is committed. 461s -- ---- 461s begin 461s lock table public.sl_log_1 in access exclusive mode nowait; 461s exception when lock_not_available then 461s raise notice 'Slony-I: could not lock sl_log_1 - sl_log_1 not truncated'; 461s return -1; 461s end; 461s 461s -- ---- 461s -- The cleanup thread calls us after it did the delete and 461s -- vacuum of both log tables. If sl_log_2 is empty now, we 461s -- can truncate it and the log switch is done. 461s -- ---- 461s for v_origin, v_seqno, v_xmin in 461s select ev_origin, ev_seqno, "pg_catalog".txid_snapshot_xmin(ev_snapshot) from public.sl_event 461s where (ev_origin, ev_seqno) in (select ev_origin, min(ev_seqno) from public.sl_event where ev_type = 'SYNC' group by ev_origin) 461s loop 461s if (exists (select 1 from public.sl_log_1 where log_origin = v_origin and log_txid >= v_xmin limit 1)) then 461s v_purgeable := 'false'; 461s end if; 461s end loop; 461s if not v_purgeable then 461s -- ---- 461s -- Found a row ... log switch is still in progress. 461s -- ---- 461s raise notice 'Slony-I: log switch to sl_log_2 still in progress - sl_log_1 not truncated'; 461s return -1; 461s end if; 461s 461s raise notice 'Slony-I: log switch to sl_log_2 complete - truncate sl_log_1'; 461s truncate public.sl_log_1; 461s if exists (select * from "pg_catalog".pg_class c, "pg_catalog".pg_namespace n, "pg_catalog".pg_attribute a where c.relname = 'sl_log_1' and n.oid = c.relnamespace and a.attrelid = c.oid and a.attname = 'oid') then 461s execute 'alter table public.sl_log_1 set without oids;'; 461s end if; 461s perform "pg_catalog".setval('public.sl_log_status', 1); 461s -- Run addPartialLogIndices() to try to add indices to unused sl_log_? table 461s perform public.addPartialLogIndices(); 461s return 2; 461s end if; 461s END; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.logswitch_finish() is 461s 'logswitch_finish() 461s 461s Attempt to finalize a log table switch in progress 461s return values: 461s -1 if switch in progress, but not complete 461s 0 if no switch in progress 461s 1 if performed truncate on sl_log_2 461s 2 if performed truncate on sl_log_1 461s '; 461s COMMENT 461s create or replace function public.addPartialLogIndices () returns integer as $$ 461s DECLARE 461s v_current_status int4; 461s v_log int4; 461s v_dummy record; 461s v_dummy2 record; 461s idef text; 461s v_count int4; 461s v_iname text; 461s v_ilen int4; 461s v_maxlen int4; 461s BEGIN 461s v_count := 0; 461s select last_value into v_current_status from public.sl_log_status; 461s 461s -- If status is 2 or 3 --> in process of cleanup --> unsafe to create indices 461s if v_current_status in (2, 3) then 461s return 0; 461s end if; 461s 461s if v_current_status = 0 then -- Which log should get indices? 461s v_log := 2; 461s else 461s v_log := 1; 461s end if; 461s -- PartInd_test_db_sl_log_2-node-1 461s -- Add missing indices... 461s for v_dummy in select distinct set_origin from public.sl_set loop 461s v_iname := 'PartInd_main_sl_log_' || v_log::text || '-node-' 461s || v_dummy.set_origin::text; 461s -- raise notice 'Consider adding partial index % on sl_log_%', v_iname, v_log; 461s -- raise notice 'schema: [_main] tablename:[sl_log_%]', v_log; 461s select * into v_dummy2 from pg_catalog.pg_indexes where tablename = 'sl_log_' || v_log::text and indexname = v_iname; 461s if not found then 461s -- raise notice 'index was not found - add it!'; 461s v_iname := 'PartInd_main_sl_log_' || v_log::text || '-node-' || v_dummy.set_origin::text; 461s v_ilen := pg_catalog.length(v_iname); 461s v_maxlen := pg_catalog.current_setting('max_identifier_length'::text)::int4; 461s if v_ilen > v_maxlen then 461s raise exception 'Length of proposed index name [%] > max_identifier_length [%] - cluster name probably too long', v_ilen, v_maxlen; 461s end if; 461s 461s idef := 'create index "' || v_iname || 461s '" on public.sl_log_' || v_log::text || ' USING btree(log_txid) where (log_origin = ' || v_dummy.set_origin::text || ');'; 461s execute idef; 461s v_count := v_count + 1; 461s else 461s -- raise notice 'Index % already present - skipping', v_iname; 461s end if; 461s end loop; 461s 461s -- Remove unneeded indices... 461s for v_dummy in select indexname from pg_catalog.pg_indexes i where i.tablename = 'sl_log_' || v_log::text and 461s i.indexname like ('PartInd_main_sl_log_' || v_log::text || '-node-%') and 461s not exists (select 1 from public.sl_set where 461s i.indexname = 'PartInd_main_sl_log_' || v_log::text || '-node-' || set_origin::text) 461s loop 461s -- raise notice 'Dropping obsolete index %d', v_dummy.indexname; 461s idef := 'drop index public."' || v_dummy.indexname || '";'; 461s execute idef; 461s v_count := v_count - 1; 461s end loop; 461s return v_count; 461s END 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.addPartialLogIndices () is 461s 'Add partial indexes, if possible, to the unused sl_log_? table for 461s all origin nodes, and drop any that are no longer needed. 461s 461s This function presently gets run any time set origins are manipulated 461s (FAILOVER, STORE SET, MOVE SET, DROP SET), as well as each time the 461s system switches between sl_log_1 and sl_log_2.'; 461s COMMENT 461s create or replace function public.check_table_field_exists (p_namespace text, p_table text, p_field text) 461s returns bool as $$ 461s BEGIN 461s return exists ( 461s select 1 from "information_schema".columns 461s where table_schema = p_namespace 461s and table_name = p_table 461s and column_name = p_field 461s ); 461s END;$$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.check_table_field_exists (p_namespace text, p_table text, p_field text) 461s is 'Check if a table has a specific attribute'; 461s COMMENT 461s create or replace function public.add_missing_table_field (p_namespace text, p_table text, p_field text, p_type text) 461s returns bool as $$ 461s DECLARE 461s v_row record; 461s v_query text; 461s BEGIN 461s if not public.check_table_field_exists(p_namespace, p_table, p_field) then 461s raise notice 'Upgrade table %.% - add field %', p_namespace, p_table, p_field; 461s v_query := 'alter table ' || p_namespace || '.' || p_table || ' add column '; 461s v_query := v_query || p_field || ' ' || p_type || ';'; 461s execute v_query; 461s return 't'; 461s else 461s return 'f'; 461s end if; 461s END;$$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.add_missing_table_field (p_namespace text, p_table text, p_field text, p_type text) 461s is 'Add a column of a given type to a table if it is missing'; 461s COMMENT 461s create or replace function public.upgradeSchema(p_old text) 461s returns text as $$ 461s declare 461s v_tab_row record; 461s v_query text; 461s v_keepstatus text; 461s begin 461s -- If old version is pre-2.0, then we require a special upgrade process 461s if p_old like '1.%' then 461s raise exception 'Upgrading to Slony-I 2.x requires running slony_upgrade_20'; 461s end if; 461s 461s perform public.upgradeSchemaAddTruncateTriggers(); 461s 461s -- Change all Slony-I-defined columns that are "timestamp without time zone" to "timestamp *WITH* time zone" 461s if exists (select 1 from information_schema.columns c 461s where table_schema = '_main' and data_type = 'timestamp without time zone' 461s and exists (select 1 from information_schema.tables t where t.table_schema = c.table_schema and t.table_name = c.table_name and t.table_type = 'BASE TABLE') 461s and (c.table_name, c.column_name) in (('sl_confirm', 'con_timestamp'), ('sl_event', 'ev_timestamp'), ('sl_registry', 'reg_timestamp'),('sl_archive_counter', 'ac_timestamp'))) 461s then 461s 461s -- Preserve sl_status 461s select pg_get_viewdef('public.sl_status') into v_keepstatus; 461s execute 'drop view sl_status'; 461s for v_tab_row in select table_schema, table_name, column_name from information_schema.columns c 461s where table_schema = '_main' and data_type = 'timestamp without time zone' 461s and exists (select 1 from information_schema.tables t where t.table_schema = c.table_schema and t.table_name = c.table_name and t.table_type = 'BASE TABLE') 461s and (table_name, column_name) in (('sl_confirm', 'con_timestamp'), ('sl_event', 'ev_timestamp'), ('sl_registry', 'reg_timestamp'),('sl_archive_counter', 'ac_timestamp')) 461s loop 461s raise notice 'Changing Slony-I column [%.%] to timestamp WITH time zone', v_tab_row.table_name, v_tab_row.column_name; 461s v_query := 'alter table ' || public.slon_quote_brute(v_tab_row.table_schema) || 461s '.' || v_tab_row.table_name || ' alter column ' || v_tab_row.column_name || 461s ' type timestamp with time zone;'; 461s execute v_query; 461s end loop; 461s -- restore sl_status 461s execute 'create view sl_status as ' || v_keepstatus; 461s end if; 461s 461s if not exists (select 1 from information_schema.tables where table_schema = '_main' and table_name = 'sl_components') then 461s v_query := ' 461s create table public.sl_components ( 461s co_actor text not null primary key, 461s co_pid integer not null, 461s co_node integer not null, 461s co_connection_pid integer not null, 461s co_activity text, 461s co_starttime timestamptz not null, 461s co_event bigint, 461s co_eventtype text 461s ) without oids; 461s '; 461s execute v_query; 461s end if; 461s 461s 461s 461s 461s 461s if not exists (select 1 from information_schema.tables t where table_schema = '_main' and table_name = 'sl_event_lock') then 461s v_query := 'create table public.sl_event_lock (dummy integer);'; 461s execute v_query; 461s end if; 461s 461s if not exists (select 1 from information_schema.tables t 461s where table_schema = '_main' 461s and table_name = 'sl_apply_stats') then 461s v_query := ' 461s create table public.sl_apply_stats ( 461s as_origin int4, 461s as_num_insert int8, 461s as_num_update int8, 461s as_num_delete int8, 461s as_num_truncate int8, 461s as_num_script int8, 461s as_num_total int8, 461s as_duration interval, 461s as_apply_first timestamptz, 461s as_apply_last timestamptz, 461s as_cache_prepare int8, 461s as_cache_hit int8, 461s as_cache_evict int8, 461s as_cache_prepare_max int8 461s ) WITHOUT OIDS;'; 461s execute v_query; 461s end if; 461s 461s -- 461s -- On the upgrade to 2.2, we change the layout of sl_log_N by 461s -- adding columns log_tablenspname, log_tablerelname, and 461s -- log_cmdupdncols as well as changing log_cmddata into 461s -- log_cmdargs, which is a text array. 461s -- 461s if not public.check_table_field_exists('_main', 'sl_log_1', 'log_cmdargs') then 461s -- 461s -- Check that the cluster is completely caught up 461s -- 461s if public.check_unconfirmed_log() then 461s raise EXCEPTION 'cannot upgrade to new sl_log_N format due to existing unreplicated data'; 461s end if; 461s 461s -- 461s -- Drop tables sl_log_1 and sl_log_2 461s -- 461s drop table public.sl_log_1; 461s drop table public.sl_log_2; 461s 461s -- 461s -- Create the new sl_log_1 461s -- 461s create table public.sl_log_1 ( 461s log_origin int4, 461s log_txid bigint, 461s log_tableid int4, 461s log_actionseq int8, 461s log_tablenspname text, 461s log_tablerelname text, 461s log_cmdtype "char", 461s log_cmdupdncols int4, 461s log_cmdargs text[] 461s ) without oids; 461s create index sl_log_1_idx1 on public.sl_log_1 461s (log_origin, log_txid, log_actionseq); 461s 461s comment on table public.sl_log_1 is 'Stores each change to be propagated to subscriber nodes'; 461s comment on column public.sl_log_1.log_origin is 'Origin node from which the change came'; 461s comment on column public.sl_log_1.log_txid is 'Transaction ID on the origin node'; 461s comment on column public.sl_log_1.log_tableid is 'The table ID (from sl_table.tab_id) that this log entry is to affect'; 461s comment on column public.sl_log_1.log_actionseq is 'The sequence number in which actions will be applied on replicas'; 461s comment on column public.sl_log_1.log_tablenspname is 'The schema name of the table affected'; 461s comment on column public.sl_log_1.log_tablerelname is 'The table name of the table affected'; 461s comment on column public.sl_log_1.log_cmdtype is 'Replication action to take. U = Update, I = Insert, D = DELETE, T = TRUNCATE'; 461s comment on column public.sl_log_1.log_cmdupdncols is 'For cmdtype=U the number of updated columns in cmdargs'; 461s comment on column public.sl_log_1.log_cmdargs is 'The data needed to perform the log action on the replica'; 461s 461s -- 461s -- Create the new sl_log_2 461s -- 461s create table public.sl_log_2 ( 461s log_origin int4, 461s log_txid bigint, 461s log_tableid int4, 461s log_actionseq int8, 461s log_tablenspname text, 461s log_tablerelname text, 461s log_cmdtype "char", 461s log_cmdupdncols int4, 461s log_cmdargs text[] 461s ) without oids; 461s create index sl_log_2_idx1 on public.sl_log_2 461s (log_origin, log_txid, log_actionseq); 461s 461s comment on table public.sl_log_2 is 'Stores each change to be propagated to subscriber nodes'; 461s comment on column public.sl_log_2.log_origin is 'Origin node from which the change came'; 461s comment on column public.sl_log_2.log_txid is 'Transaction ID on the origin node'; 461s comment on column public.sl_log_2.log_tableid is 'The table ID (from sl_table.tab_id) that this log entry is to affect'; 461s comment on column public.sl_log_2.log_actionseq is 'The sequence number in which actions will be applied on replicas'; 461s comment on column public.sl_log_2.log_tablenspname is 'The schema name of the table affected'; 461s comment on column public.sl_log_2.log_tablerelname is 'The table name of the table affected'; 461s comment on column public.sl_log_2.log_cmdtype is 'Replication action to take. U = Update, I = Insert, D = DELETE, T = TRUNCATE'; 461s comment on column public.sl_log_2.log_cmdupdncols is 'For cmdtype=U the number of updated columns in cmdargs'; 461s comment on column public.sl_log_2.log_cmdargs is 'The data needed to perform the log action on the replica'; 461s 461s create table public.sl_log_script ( 461s log_origin int4, 461s log_txid bigint, 461s log_actionseq int8, 461s log_cmdtype "char", 461s log_cmdargs text[] 461s ) WITHOUT OIDS; 461s create index sl_log_script_idx1 on public.sl_log_script 461s (log_origin, log_txid, log_actionseq); 461s 461s comment on table public.sl_log_script is 'Captures SQL script queries to be propagated to subscriber nodes'; 461s comment on column public.sl_log_script.log_origin is 'Origin name from which the change came'; 461s comment on column public.sl_log_script.log_txid is 'Transaction ID on the origin node'; 461s comment on column public.sl_log_script.log_actionseq is 'The sequence number in which actions will be applied on replicas'; 461s comment on column public.sl_log_2.log_cmdtype is 'Replication action to take. S = Script statement, s = Script complete'; 461s comment on column public.sl_log_script.log_cmdargs is 'The DDL statement, optionally followed by selected nodes to execute it on.'; 461s 461s -- 461s -- Put the log apply triggers back onto sl_log_1/2 461s -- 461s create trigger apply_trigger 461s before INSERT on public.sl_log_1 461s for each row execute procedure public.logApply('_main'); 461s alter table public.sl_log_1 461s enable replica trigger apply_trigger; 461s create trigger apply_trigger 461s before INSERT on public.sl_log_2 461s for each row execute procedure public.logApply('_main'); 461s alter table public.sl_log_2 461s enable replica trigger apply_trigger; 461s end if; 461s if not exists (select 1 from information_schema.routines where routine_schema = '_main' and routine_name = 'string_agg') then 461s CREATE AGGREGATE public.string_agg(text) ( 461s SFUNC=public.agg_text_sum, 461s STYPE=text, 461s INITCOND='' 461s ); 461s end if; 461s if not exists (select 1 from information_schema.views where table_schema='_main' and table_name='sl_failover_targets') then 461s create view public.sl_failover_targets as 461s select set_id, 461s set_origin as set_origin, 461s sub1.sub_receiver as backup_id 461s 461s FROM 461s public.sl_subscribe sub1 461s ,public.sl_set set1 461s where 461s sub1.sub_set=set_id 461s and sub1.sub_forward=true 461s --exclude candidates where the set_origin 461s --has a path a node but the failover 461s --candidate has no path to that node 461s and sub1.sub_receiver not in 461s (select p1.pa_client from 461s public.sl_path p1 461s left outer join public.sl_path p2 on 461s (p2.pa_client=p1.pa_client 461s and p2.pa_server=sub1.sub_receiver) 461s where p2.pa_client is null 461s and p1.pa_server=set_origin 461s and p1.pa_client<>sub1.sub_receiver 461s ) 461s and sub1.sub_provider=set_origin 461s --exclude any subscribers that are not 461s --direct subscribers of all sets on the 461s --origin 461s and sub1.sub_receiver not in 461s (select direct_recv.sub_receiver 461s from 461s 461s (--all direct receivers of the first set 461s select subs2.sub_receiver 461s from public.sl_subscribe subs2 461s where subs2.sub_provider=set1.set_origin 461s and subs2.sub_set=set1.set_id) as 461s direct_recv 461s inner join 461s (--all other sets from the origin 461s select set_id from public.sl_set set2 461s where set2.set_origin=set1.set_origin 461s and set2.set_id<>sub1.sub_set) 461s as othersets on(true) 461s left outer join public.sl_subscribe subs3 461s on(subs3.sub_set=othersets.set_id 461s and subs3.sub_forward=true 461s and subs3.sub_provider=set1.set_origin 461s and direct_recv.sub_receiver=subs3.sub_receiver) 461s where subs3.sub_receiver is null 461s ); 461s end if; 461s 461s if not public.check_table_field_exists('_main', 'sl_node', 'no_failed') then 461s alter table public.sl_node add column no_failed bool; 461s update public.sl_node set no_failed=false; 461s end if; 461s return p_old; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s create or replace function public.check_unconfirmed_log () 461s returns bool as $$ 461s declare 461s v_rc bool = false; 461s v_error bool = false; 461s v_origin integer; 461s v_allconf bigint; 461s v_allsnap txid_snapshot; 461s v_count bigint; 461s begin 461s -- 461s -- Loop over all nodes that are the origin of at least one set 461s -- 461s for v_origin in select distinct set_origin as no_id 461s from public.sl_set loop 461s -- 461s -- Per origin determine which is the highest event seqno 461s -- that is confirmed by all subscribers to any of the 461s -- origins sets. 461s -- 461s select into v_allconf min(max_seqno) from ( 461s select con_received, max(con_seqno) as max_seqno 461s from public.sl_confirm 461s where con_origin = v_origin 461s and con_received in ( 461s select distinct sub_receiver 461s from public.sl_set as SET, 461s public.sl_subscribe as SUB 461s where SET.set_id = SUB.sub_set 461s and SET.set_origin = v_origin 461s ) 461s group by con_received 461s ) as maxconfirmed; 461s if not found then 461s raise NOTICE 'check_unconfirmed_log(): cannot determine highest ev_seqno for node % confirmed by all subscribers', v_origin; 461s v_error = true; 461s continue; 461s end if; 461s 461s -- 461s -- Get the txid snapshot that corresponds with that event 461s -- 461s select into v_allsnap ev_snapshot 461s from public.sl_event 461s where ev_origin = v_origin 461s and ev_seqno = v_allconf; 461s if not found then 461s raise NOTICE 'check_unconfirmed_log(): cannot find event %,% in sl_event', v_origin, v_allconf; 461s v_error = true; 461s continue; 461s end if; 461s 461s -- 461s -- Count the number of log rows that appeard after that event. 461s -- 461s select into v_count count(*) from ( 461s select 1 from public.sl_log_1 461s where log_origin = v_origin 461s and log_txid >= "pg_catalog".txid_snapshot_xmax(v_allsnap) 461s union all 461s select 1 from public.sl_log_1 461s where log_origin = v_origin 461s and log_txid in ( 461s select * from "pg_catalog".txid_snapshot_xip(v_allsnap) 461s ) 461s union all 461s select 1 from public.sl_log_2 461s where log_origin = v_origin 461s and log_txid >= "pg_catalog".txid_snapshot_xmax(v_allsnap) 461s union all 461s select 1 from public.sl_log_2 461s where log_origin = v_origin 461s and log_txid in ( 461s select * from "pg_catalog".txid_snapshot_xip(v_allsnap) 461s ) 461s ) as cnt; 461s 461s if v_count > 0 then 461s raise NOTICE 'check_unconfirmed_log(): origin % has % log rows that have not propagated to all subscribers yet', v_origin, v_count; 461s v_rc = true; 461s end if; 461s end loop; 461s 461s if v_error then 461s raise EXCEPTION 'check_unconfirmed_log(): aborting due to previous inconsistency'; 461s end if; 461s 461s return v_rc; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s set search_path to public 461s ; 461s SET 461s comment on function public.upgradeSchema(p_old text) is 461s 'Called during "update functions" by slonik to perform schema changes'; 461s COMMENT 461s create or replace view public.sl_status as select 461s E.ev_origin as st_origin, 461s C.con_received as st_received, 461s E.ev_seqno as st_last_event, 461s E.ev_timestamp as st_last_event_ts, 461s C.con_seqno as st_last_received, 461s C.con_timestamp as st_last_received_ts, 461s CE.ev_timestamp as st_last_received_event_ts, 461s E.ev_seqno - C.con_seqno as st_lag_num_events, 461s current_timestamp - CE.ev_timestamp as st_lag_time 461s from public.sl_event E, public.sl_confirm C, 461s public.sl_event CE 461s where E.ev_origin = C.con_origin 461s and CE.ev_origin = E.ev_origin 461s and CE.ev_seqno = C.con_seqno 461s and (E.ev_origin, E.ev_seqno) in 461s (select ev_origin, max(ev_seqno) 461s from public.sl_event 461s where ev_origin = public.getLocalNodeId('_main') 461s group by 1 461s ) 461s and (C.con_origin, C.con_received, C.con_seqno) in 461s (select con_origin, con_received, max(con_seqno) 461s from public.sl_confirm 461s where con_origin = public.getLocalNodeId('_main') 461s group by 1, 2 461s ); 461s CREATE VIEW 461s comment on view public.sl_status is 'View showing how far behind remote nodes are.'; 461s COMMENT 461s create or replace function public.copyFields(p_tab_id integer) 461s returns text 461s as $$ 461s declare 461s result text; 461s prefix text; 461s prec record; 461s begin 461s result := ''; 461s prefix := '('; -- Initially, prefix is the opening paren 461s 461s for prec in select public.slon_quote_input(a.attname) as column from public.sl_table t, pg_catalog.pg_attribute a where t.tab_id = p_tab_id and t.tab_reloid = a.attrelid and a.attnum > 0 and a.attisdropped = false order by attnum 461s loop 461s result := result || prefix || prec.column; 461s prefix := ','; -- Subsequently, prepend columns with commas 461s end loop; 461s result := result || ')'; 461s return result; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.copyFields(p_tab_id integer) is 461s 'Return a string consisting of what should be appended to a COPY statement 461s to specify fields for the passed-in tab_id. 461s 461s In PG versions > 7.3, this looks like (field1,field2,...fieldn)'; 461s COMMENT 461s create or replace function public.prepareTableForCopy(p_tab_id int4) 461s returns int4 461s as $$ 461s declare 461s v_tab_oid oid; 461s v_tab_fqname text; 461s begin 461s -- ---- 461s -- Get the OID and fully qualified name for the table 461s -- --- 461s select PGC.oid, 461s public.slon_quote_brute(PGN.nspname) || '.' || 461s public.slon_quote_brute(PGC.relname) as tab_fqname 461s into v_tab_oid, v_tab_fqname 461s from public.sl_table T, 461s "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN 461s where T.tab_id = p_tab_id 461s and T.tab_reloid = PGC.oid 461s and PGC.relnamespace = PGN.oid; 461s if not found then 461s raise exception 'Table with ID % not found in sl_table', p_tab_id; 461s end if; 461s 461s -- ---- 461s -- Try using truncate to empty the table and fallback to 461s -- delete on error. 461s -- ---- 461s perform public.TruncateOnlyTable(v_tab_fqname); 461s raise notice 'truncate of % succeeded', v_tab_fqname; 461s 461s -- suppress index activity 461s perform public.disable_indexes_on_table(v_tab_oid); 461s 461s return 1; 461s exception when others then 461s raise notice 'truncate of % failed - doing delete', v_tab_fqname; 461s perform public.disable_indexes_on_table(v_tab_oid); 461s execute 'delete from only ' || public.slon_quote_input(v_tab_fqname); 461s return 0; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.prepareTableForCopy(p_tab_id int4) is 461s 'Delete all data and suppress index maintenance'; 461s COMMENT 461s create or replace function public.finishTableAfterCopy(p_tab_id int4) 461s returns int4 461s as $$ 461s declare 461s v_tab_oid oid; 461s v_tab_fqname text; 461s begin 461s -- ---- 461s -- Get the tables OID and fully qualified name 461s -- --- 461s select PGC.oid, 461s public.slon_quote_brute(PGN.nspname) || '.' || 461s public.slon_quote_brute(PGC.relname) as tab_fqname 461s into v_tab_oid, v_tab_fqname 461s from public.sl_table T, 461s "pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN 461s where T.tab_id = p_tab_id 461s and T.tab_reloid = PGC.oid 461s and PGC.relnamespace = PGN.oid; 461s if not found then 461s raise exception 'Table with ID % not found in sl_table', p_tab_id; 461s end if; 461s 461s -- ---- 461s -- Reenable indexes and reindex the table. 461s -- ---- 461s perform public.enable_indexes_on_table(v_tab_oid); 461s execute 'reindex table ' || public.slon_quote_input(v_tab_fqname); 461s 461s return 1; 461s end; 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.finishTableAfterCopy(p_tab_id int4) is 461s 'Reenable index maintenance and reindex the table'; 461s COMMENT 461s create or replace function public.setup_vactables_type () returns integer as $$ 461s begin 461s if not exists (select 1 from pg_catalog.pg_type t, pg_catalog.pg_namespace n 461s where n.nspname = '_main' and t.typnamespace = n.oid and 461s t.typname = 'vactables') then 461s execute 'create type public.vactables as (nspname name, relname name);'; 461s end if; 461s return 1; 461s end 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.setup_vactables_type () is 461s 'Function to be run as part of loading slony1_funcs.sql that creates the vactables type if it is missing'; 461s COMMENT 461s select public.setup_vactables_type(); 461s setup_vactables_type 461s ---------------------- 461s 1 461s (1 row) 461s 461s drop function public.setup_vactables_type (); 461s DROP FUNCTION 461s create or replace function public.TablesToVacuum () returns setof public.vactables as $$ 461s declare 461s prec public.vactables%rowtype; 461s begin 461s prec.nspname := '_main'; 461s prec.relname := 'sl_event'; 461s if public.ShouldSlonyVacuumTable(prec.nspname, prec.relname) then 461s return next prec; 461s end if; 461s prec.nspname := '_main'; 461s prec.relname := 'sl_confirm'; 461s if public.ShouldSlonyVacuumTable(prec.nspname, prec.relname) then 461s return next prec; 461s end if; 461s prec.nspname := '_main'; 461s prec.relname := 'sl_setsync'; 461s if public.ShouldSlonyVacuumTable(prec.nspname, prec.relname) then 461s return next prec; 461s end if; 461s prec.nspname := '_main'; 461s prec.relname := 'sl_seqlog'; 461s if public.ShouldSlonyVacuumTable(prec.nspname, prec.relname) then 461s return next prec; 461s end if; 461s prec.nspname := '_main'; 461s prec.relname := 'sl_archive_counter'; 461s if public.ShouldSlonyVacuumTable(prec.nspname, prec.relname) then 461s return next prec; 461s end if; 461s prec.nspname := '_main'; 461s prec.relname := 'sl_components'; 461s if public.ShouldSlonyVacuumTable(prec.nspname, prec.relname) then 461s return next prec; 461s end if; 461s prec.nspname := '_main'; 461s prec.relname := 'sl_log_script'; 461s if public.ShouldSlonyVacuumTable(prec.nspname, prec.relname) then 461s return next prec; 461s end if; 461s prec.nspname := 'pg_catalog'; 461s prec.relname := 'pg_listener'; 461s if public.ShouldSlonyVacuumTable(prec.nspname, prec.relname) then 461s return next prec; 461s end if; 461s prec.nspname := 'pg_catalog'; 461s prec.relname := 'pg_statistic'; 461s if public.ShouldSlonyVacuumTable(prec.nspname, prec.relname) then 461s return next prec; 461s end if; 461s 461s return; 461s end 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.TablesToVacuum () is 461s 'Return a list of tables that require frequent vacuuming. The 461s function is used so that the list is not hardcoded into C code.'; 461s COMMENT 461s create or replace function public.add_empty_table_to_replication(p_set_id int4, p_tab_id int4, p_nspname text, p_tabname text, p_idxname text, p_comment text) returns bigint as $$ 461s declare 461s 461s prec record; 461s v_origin int4; 461s v_isorigin boolean; 461s v_fqname text; 461s v_query text; 461s v_rows integer; 461s v_idxname text; 461s 461s begin 461s -- Need to validate that the set exists; the set will tell us if this is the origin 461s select set_origin into v_origin from public.sl_set where set_id = p_set_id; 461s if not found then 461s raise exception 'add_empty_table_to_replication: set % not found!', p_set_id; 461s end if; 461s 461s -- Need to be aware of whether or not this node is origin for the set 461s v_isorigin := ( v_origin = public.getLocalNodeId('_main') ); 461s 461s v_fqname := '"' || p_nspname || '"."' || p_tabname || '"'; 461s -- Take out a lock on the table 461s v_query := 'lock ' || v_fqname || ';'; 461s execute v_query; 461s 461s if v_isorigin then 461s -- On the origin, verify that the table is empty, failing if it has any tuples 461s v_query := 'select 1 as tuple from ' || v_fqname || ' limit 1;'; 461s execute v_query into prec; 461s GET DIAGNOSTICS v_rows = ROW_COUNT; 461s if v_rows = 0 then 461s raise notice 'add_empty_table_to_replication: table % empty on origin - OK', v_fqname; 461s else 461s raise exception 'add_empty_table_to_replication: table % contained tuples on origin node %', v_fqname, v_origin; 461s end if; 461s else 461s -- On other nodes, TRUNCATE the table 461s v_query := 'truncate ' || v_fqname || ';'; 461s execute v_query; 461s end if; 461s -- If p_idxname is NULL, then look up the PK index, and RAISE EXCEPTION if one does not exist 461s if p_idxname is NULL then 461s select c2.relname into prec from pg_catalog.pg_index i, pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_namespace n where i.indrelid = c1.oid and i.indexrelid = c2.oid and c1.relname = p_tabname and i.indisprimary and n.nspname = p_nspname and n.oid = c1.relnamespace; 461s if not found then 461s raise exception 'add_empty_table_to_replication: table % has no primary key and no candidate specified!', v_fqname; 461s else 461s v_idxname := prec.relname; 461s end if; 461s else 461s v_idxname := p_idxname; 461s end if; 461s return public.setAddTable_int(p_set_id, p_tab_id, v_fqname, v_idxname, p_comment); 461s end 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.add_empty_table_to_replication(p_set_id int4, p_tab_id int4, p_nspname text, p_tabname text, p_idxname text, p_comment text) is 461s 'Verify that a table is empty, and add it to replication. 461s tab_idxname is optional - if NULL, then we use the primary key. 461s 461s Note that this function is to be run within an EXECUTE SCRIPT script, 461s so it runs at the right place in the transaction stream on all 461s nodes.'; 461s COMMENT 461s create or replace function public.replicate_partition(p_tab_id int4, p_nspname text, p_tabname text, p_idxname text, p_comment text) returns bigint as $$ 461s declare 461s prec record; 461s prec2 record; 461s v_set_id int4; 461s 461s begin 461s -- Look up the parent table; fail if it does not exist 461s select c1.oid into prec from pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_inherits i, pg_catalog.pg_namespace n where c1.oid = i.inhparent and c2.oid = i.inhrelid and n.oid = c2.relnamespace and n.nspname = p_nspname and c2.relname = p_tabname; 461s if not found then 461s raise exception 'replicate_partition: No parent table found for %.%!', p_nspname, p_tabname; 461s end if; 461s 461s -- The parent table tells us what replication set to use 461s select tab_set into prec2 from public.sl_table where tab_reloid = prec.oid; 461s if not found then 461s raise exception 'replicate_partition: Parent table % for new partition %.% is not replicated!', prec.oid, p_nspname, p_tabname; 461s end if; 461s 461s v_set_id := prec2.tab_set; 461s 461s -- Now, we have all the parameters necessary to run add_empty_table_to_replication... 461s return public.add_empty_table_to_replication(v_set_id, p_tab_id, p_nspname, p_tabname, p_idxname, p_comment); 461s end 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.replicate_partition(p_tab_id int4, p_nspname text, p_tabname text, p_idxname text, p_comment text) is 461s 'Add a partition table to replication. 461s tab_idxname is optional - if NULL, then we use the primary key. 461s This function looks up replication configuration via the parent table. 461s 461s Note that this function is to be run within an EXECUTE SCRIPT script, 461s so it runs at the right place in the transaction stream on all 461s nodes.'; 461s COMMENT 461s create or replace function public.disable_indexes_on_table (i_oid oid) 461s returns integer as $$ 461s begin 461s -- Setting pg_class.relhasindex to false will cause copy not to 461s -- maintain any indexes. At the end of the copy we will reenable 461s -- them and reindex the table. This bulk creating of indexes is 461s -- faster. 461s 461s update pg_catalog.pg_class set relhasindex ='f' where oid = i_oid; 461s return 1; 461s end $$ 461s language plpgsql; 461s CREATE FUNCTION 461s comment on function public.disable_indexes_on_table(i_oid oid) is 461s 'disable indexes on the specified table. 461s Used during subscription process to suppress indexes, which allows 461s COPY to go much faster. 461s 461s This may be set as a SECURITY DEFINER in order to eliminate the need 461s for superuser access by Slony-I. 461s '; 461s COMMENT 461s create or replace function public.enable_indexes_on_table (i_oid oid) 461s returns integer as $$ 461s begin 461s update pg_catalog.pg_class set relhasindex ='t' where oid = i_oid; 461s return 1; 461s end $$ 461s language plpgsql 461s security definer; 461s CREATE FUNCTION 461s comment on function public.enable_indexes_on_table(i_oid oid) is 461s 're-enable indexes on the specified table. 461s 461s This may be set as a SECURITY DEFINER in order to eliminate the need 461s for superuser access by Slony-I. 461s '; 461s COMMENT 461s drop function if exists public.reshapeSubscription(int4,int4,int4); 461s DROP FUNCTION 461s create or replace function public.reshapeSubscription (p_sub_origin int4, p_sub_provider int4, p_sub_receiver int4) returns int4 as $$ 461s begin 461s update public.sl_subscribe 461s set sub_provider=p_sub_provider 461s from public.sl_set 461s WHERE sub_set=sl_set.set_id 461s and sl_set.set_origin=p_sub_origin and sub_receiver=p_sub_receiver; 461s if found then 461s perform public.RebuildListenEntries(); 461s notify "_main_Restart"; 461s end if; 461s return 0; 461s end 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.reshapeSubscription(p_sub_origin int4, p_sub_provider int4, p_sub_receiver int4) is 461s 'Run on a receiver/subscriber node when the provider for that 461s subscription is being changed. Slonik will invoke this method 461s before the SUBSCRIBE_SET event propogates to the receiver 461s so listen paths can be updated.'; 461s COMMENT 461s create or replace function public.slon_node_health_check() returns boolean as $$ 461s declare 461s prec record; 461s all_ok boolean; 461s begin 461s all_ok := 't'::boolean; 461s -- validate that all tables in sl_table have: 461s -- sl_table agreeing with pg_class 461s for prec in select tab_id, tab_relname, tab_nspname from 461s public.sl_table t where not exists (select 1 from pg_catalog.pg_class c, pg_catalog.pg_namespace n 461s where c.oid = t.tab_reloid and c.relname = t.tab_relname and c.relnamespace = n.oid and n.nspname = t.tab_nspname) loop 461s all_ok := 'f'::boolean; 461s raise warning 'table [id,nsp,name]=[%,%,%] - sl_table does not match pg_class/pg_namespace', prec.tab_id, prec.tab_relname, prec.tab_nspname; 461s end loop; 461s if not all_ok then 461s raise warning 'Mismatch found between sl_table and pg_class. Slonik command REPAIR CONFIG may be useful to rectify this.'; 461s end if; 461s return all_ok; 461s end 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.slon_node_health_check() is 'called when slon starts up to validate that there are not problems with node configuration. Returns t if all is OK, f if there is a problem.'; 461s COMMENT 461s create or replace function public.log_truncate () returns trigger as 461s $$ 461s declare 461s r_role text; 461s c_nspname text; 461s c_relname text; 461s c_log integer; 461s c_node integer; 461s c_tabid integer; 461s begin 461s -- Ignore this call if session_replication_role = 'local' 461s select into r_role setting 461s from pg_catalog.pg_settings where name = 'session_replication_role'; 461s if r_role = 'local' then 461s return NULL; 461s end if; 461s 461s c_tabid := tg_argv[0]; 461s c_node := public.getLocalNodeId('_main'); 461s select tab_nspname, tab_relname into c_nspname, c_relname 461s from public.sl_table where tab_id = c_tabid; 461s select last_value into c_log from public.sl_log_status; 461s if c_log in (0, 2) then 461s insert into public.sl_log_1 ( 461s log_origin, log_txid, log_tableid, 461s log_actionseq, log_tablenspname, 461s log_tablerelname, log_cmdtype, 461s log_cmdupdncols, log_cmdargs 461s ) values ( 461s c_node, pg_catalog.txid_current(), c_tabid, 461s nextval('public.sl_action_seq'), c_nspname, 461s c_relname, 'T', 0, '{}'::text[]); 461s else -- (1, 3) 461s insert into public.sl_log_2 ( 461s log_origin, log_txid, log_tableid, 461s log_actionseq, log_tablenspname, 461s log_tablerelname, log_cmdtype, 461s log_cmdupdncols, log_cmdargs 461s ) values ( 461s c_node, pg_catalog.txid_current(), c_tabid, 461s nextval('public.sl_action_seq'), c_nspname, 461s c_relname, 'T', 0, '{}'::text[]); 461s end if; 461s return NULL; 461s end 461s $$ language plpgsql 461s security definer; 461s CREATE FUNCTION 461s comment on function public.log_truncate () 461s is 'trigger function run when a replicated table receives a TRUNCATE request'; 461s COMMENT 461s create or replace function public.deny_truncate () returns trigger as 461s $$ 461s declare 461s r_role text; 461s begin 461s -- Ignore this call if session_replication_role = 'local' 461s select into r_role setting 461s from pg_catalog.pg_settings where name = 'session_replication_role'; 461s if r_role = 'local' then 461s return NULL; 461s end if; 461s 461s raise exception 'truncation of replicated table forbidden on subscriber node'; 461s end 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.deny_truncate () 461s is 'trigger function run when a replicated table receives a TRUNCATE request'; 461s COMMENT 461s create or replace function public.store_application_name (i_name text) returns text as $$ 461s declare 461s p_command text; 461s begin 461s if exists (select 1 from pg_catalog.pg_settings where name = 'application_name') then 461s p_command := 'set application_name to '''|| i_name || ''';'; 461s execute p_command; 461s return i_name; 461s end if; 461s return NULL::text; 461s end $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.store_application_name (i_name text) is 461s 'Set application_name GUC, if possible. Returns NULL if it fails to work.'; 461s COMMENT 461s create or replace function public.is_node_reachable(origin_node_id integer, 461s receiver_node_id integer) returns boolean as $$ 461s declare 461s listen_row record; 461s reachable boolean; 461s begin 461s reachable:=false; 461s select * into listen_row from public.sl_listen where 461s li_origin=origin_node_id and li_receiver=receiver_node_id; 461s if found then 461s reachable:=true; 461s end if; 461s return reachable; 461s end $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.is_node_reachable(origin_node_id integer, receiver_node_id integer) 461s is 'Is the receiver node reachable from the origin, via any of the listen paths?'; 461s COMMENT 461s create or replace function public.component_state (i_actor text, i_pid integer, i_node integer, i_conn_pid integer, i_activity text, i_starttime timestamptz, i_event bigint, i_eventtype text) returns integer as $$ 461s begin 461s -- Trim out old state for this component 461s if not exists (select 1 from public.sl_components where co_actor = i_actor) then 461s insert into public.sl_components 461s (co_actor, co_pid, co_node, co_connection_pid, co_activity, co_starttime, co_event, co_eventtype) 461s values 461s (i_actor, i_pid, i_node, i_conn_pid, i_activity, i_starttime, i_event, i_eventtype); 461s else 461s update public.sl_components 461s set 461s co_connection_pid = i_conn_pid, co_activity = i_activity, co_starttime = i_starttime, co_event = i_event, 461s co_eventtype = i_eventtype 461s where co_actor = i_actor 461s and co_starttime < i_starttime; 461s end if; 461s return 1; 461s end $$ 461s language plpgsql; 461s CREATE FUNCTION 461s comment on function public.component_state (i_actor text, i_pid integer, i_node integer, i_conn_pid integer, i_activity text, i_starttime timestamptz, i_event bigint, i_eventtype text) is 461s 'Store state of a Slony component. Useful for monitoring'; 461s COMMENT 461s create or replace function public.recreate_log_trigger(p_fq_table_name text, 461s p_tab_id oid, p_tab_attkind text) returns integer as $$ 461s begin 461s execute 'drop trigger "_main_logtrigger" on ' || 461s p_fq_table_name ; 461s -- ---- 461s execute 'create trigger "_main_logtrigger"' || 461s ' after insert or update or delete on ' || 461s p_fq_table_name 461s || ' for each row execute procedure public.logTrigger (' || 461s pg_catalog.quote_literal('_main') || ',' || 461s pg_catalog.quote_literal(p_tab_id::text) || ',' || 461s pg_catalog.quote_literal(p_tab_attkind) || ');'; 461s return 0; 461s end 461s $$ language plpgsql; 461s CREATE FUNCTION 461s comment on function public.recreate_log_trigger(p_fq_table_name text, 461s p_tab_id oid, p_tab_attkind text) is 461s 'A function that drops and recreates the log trigger on the specified table. 461s It is intended to be used after the primary_key/unique index has changed.'; 461s COMMENT 461s create or replace function public.repair_log_triggers(only_locked boolean) 461s returns integer as $$ 461s declare 461s retval integer; 461s table_row record; 461s begin 461s retval=0; 461s for table_row in 461s select tab_nspname,tab_relname, 461s tab_idxname, tab_id, mode, 461s public.determineAttKindUnique(tab_nspname|| 461s '.'||tab_relname,tab_idxname) as attkind 461s from 461s public.sl_table 461s left join 461s pg_locks on (relation=tab_reloid and pid=pg_backend_pid() 461s and mode='AccessExclusiveLock') 461s ,pg_trigger 461s where tab_reloid=tgrelid and 461s public.determineAttKindUnique(tab_nspname||'.' 461s ||tab_relname,tab_idxname) 461s !=(public.decode_tgargs(tgargs))[2] 461s and tgname = '_main' 461s || '_logtrigger' 461s LOOP 461s if (only_locked=false) or table_row.mode='AccessExclusiveLock' then 461s perform public.recreate_log_trigger 461s (table_row.tab_nspname||'.'||table_row.tab_relname, 461s table_row.tab_id,table_row.attkind); 461s retval=retval+1; 461s else 461s raise notice '%.% has an invalid configuration on the log trigger. This was not corrected because only_lock is true and the table is not locked.', 461s table_row.tab_nspname,table_row.tab_relname; 461s 461s end if; 461s end loop; 461s return retval; 461s end 461s $$ 461s language plpgsql; 461s CREATE FUNCTION 461s comment on function public.repair_log_triggers(only_locked boolean) 461s is ' 461s repair the log triggers as required. If only_locked is true then only 461s tables that are already exclusively locked by the current transaction are 461s repaired. Otherwise all replicated tables with outdated trigger arguments 461s are recreated.'; 461s COMMENT 461s create or replace function public.unsubscribe_abandoned_sets(p_failed_node int4) returns bigint 461s as $$ 461s declare 461s v_row record; 461s v_seq_id bigint; 461s v_local_node int4; 461s begin 461s 461s select public.getLocalNodeId('_main') into 461s v_local_node; 461s 461s if found then 461s --abandon all subscriptions from this origin. 461s for v_row in select sub_set,sub_receiver from 461s public.sl_subscribe, public.sl_set 461s where sub_set=set_id and set_origin=p_failed_node 461s and sub_receiver=v_local_node 461s loop 461s raise notice 'Slony-I: failover_abandon_set() is abandoning subscription to set % on node % because it is too far ahead', v_row.sub_set, 461s v_local_node; 461s --If this node is a provider for the set 461s --then the receiver needs to be unsubscribed. 461s -- 461s select public.unsubscribeSet(v_row.sub_set, 461s v_local_node,true) 461s into v_seq_id; 461s end loop; 461s end if; 461s 461s return v_seq_id; 461s end 461s $$ language plpgsql; 461s CREATE FUNCTION 461s CREATE OR replace function public.agg_text_sum(txt_before TEXT, txt_new TEXT) RETURNS TEXT AS 461s $BODY$ 461s DECLARE 461s c_delim text; 461s BEGIN 461s c_delim = ','; 461s IF (txt_before IS NULL or txt_before='') THEN 461s RETURN txt_new; 461s END IF; 461s RETURN txt_before || c_delim || txt_new; 461s END; 461s $BODY$ 461s LANGUAGE plpgsql; 461s CREATE FUNCTION 461s comment on function public.agg_text_sum(text,text) is 461s 'An accumulator function used by the slony string_agg function to 461s aggregate rows into a string'; 461s COMMENT 461s Dropping cluster 16/regress ... 461s NOTICE: function public.reshapesubscription(int4,int4,int4) does not exist, skipping 461s ### End 16 psql ### 462s autopkgtest [11:45:21]: test load-functions: -----------------------] 462s autopkgtest [11:45:21]: test load-functions: - - - - - - - - - - results - - - - - - - - - - 462s load-functions PASS 463s autopkgtest [11:45:22]: @@@@@@@@@@@@@@@@@@@@ summary 463s load-functions PASS 467s nova [W] Timed out waiting for d266e574-0d9c-4845-9e81-8f786b3b7d00 to get deleted.