Add SQL replay checkpoint object to SQL (#868)

* Add SQL replay checkpoint object to Datastore

This will be part of the asynchronous commit-log replay to SQL. Whenever
we successfully export commits up to a particular time, we should
persist that time so we don't replay the same commits again (it is not
idempotent)

* Move SqlReplayCheckpoint from DS to SQL

* Responses to CR
This commit is contained in:
gbrodman 2020-11-10 17:09:18 -05:00 committed by GitHub
parent c022aa8dc5
commit 03c246d08d
12 changed files with 387 additions and 107 deletions

View file

@ -0,0 +1,58 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.schema.replay;
import static google.registry.model.common.CrossTldSingleton.SINGLETON_ID;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import com.google.common.collect.ImmutableList;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.joda.time.DateTime;
@Entity
public class SqlReplayCheckpoint implements SqlEntity {
// Hibernate doesn't allow us to have a converted DateTime as our primary key so we need this
@Id private long revisionId = SINGLETON_ID;
private DateTime lastReplayTime;
@Override
public ImmutableList<DatastoreEntity> toDatastoreEntities() {
return ImmutableList.of(); // not necessary to persist in Datastore
}
public static DateTime get() {
jpaTm().assertInTransaction();
return jpaTm()
.getEntityManager()
.createQuery("FROM SqlReplayCheckpoint", SqlReplayCheckpoint.class)
.setMaxResults(1)
.getResultStream()
.findFirst()
.map(checkpoint -> checkpoint.lastReplayTime)
.orElse(START_OF_TIME);
}
public static void set(DateTime lastReplayTime) {
jpaTm().assertInTransaction();
SqlReplayCheckpoint checkpoint = new SqlReplayCheckpoint();
checkpoint.lastReplayTime = lastReplayTime;
// this will overwrite the existing object due to the constant revisionId
jpaTm().put(checkpoint);
}
}

View file

@ -70,6 +70,7 @@
<class>google.registry.persistence.transaction.TransactionEntity</class>
<class>google.registry.schema.cursor.Cursor</class>
<class>google.registry.schema.domain.RegistryLock</class>
<class>google.registry.schema.replay.SqlReplayCheckpoint</class>
<class>google.registry.schema.server.Lock</class>
<class>google.registry.schema.tld.PremiumEntry</class>

View file

@ -15,15 +15,11 @@
package google.registry.model.server;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.common.CrossTldSingleton.SINGLETON_ID;
import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import com.googlecode.objectify.Key;
import google.registry.model.EntityTestCase;
import google.registry.model.ofy.RequestCapturingAsyncDatastoreService;
import google.registry.persistence.VKey;
import java.util.UUID;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -85,11 +81,4 @@ public class ServerSecretTest extends EntityTestCase {
.findFirst()
.get());
}
private static VKey<ServerSecret> createKey() {
return VKey.create(
ServerSecret.class,
SINGLETON_ID,
Key.create(getCrossTldKey(), ServerSecret.class, SINGLETON_ID));
}
}

View file

@ -40,6 +40,7 @@ import google.registry.schema.cursor.CursorDaoTest;
import google.registry.schema.integration.SqlIntegrationTestSuite.AfterSuiteTest;
import google.registry.schema.integration.SqlIntegrationTestSuite.BeforeSuiteTest;
import google.registry.schema.registrar.RegistrarDaoTest;
import google.registry.schema.replay.SqlReplayCheckpointTest;
import google.registry.schema.server.LockDaoTest;
import google.registry.schema.tld.PremiumListDaoTest;
import google.registry.testing.AppEngineExtension;
@ -100,6 +101,7 @@ import org.junit.runner.RunWith;
ServerSecretTest.class,
SignedMarkRevocationListDaoTest.class,
Spec11ThreatMatchTest.class,
SqlReplayCheckpointTest.class,
TmchCrlTest.class,
// AfterSuiteTest must be the last entry. See class javadoc for details.
AfterSuiteTest.class

View file

@ -0,0 +1,61 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.schema.replay;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import google.registry.model.EntityTestCase;
import org.joda.time.DateTime;
import org.junit.jupiter.api.Test;
/** Tests for {@link SqlReplayCheckpoint}. */
public class SqlReplayCheckpointTest extends EntityTestCase {
SqlReplayCheckpointTest() {
super(JpaEntityCoverageCheck.ENABLED);
}
@Test
void testEmpty_startOfTime() {
assertThat(jpaTm().transact(SqlReplayCheckpoint::get)).isEqualTo(START_OF_TIME);
}
@Test
void testSuccess_writes() {
DateTime dateTime = DateTime.parse("2012-02-29T00:00:00Z");
jpaTm().transact(() -> SqlReplayCheckpoint.set(dateTime));
assertThat(jpaTm().transact(SqlReplayCheckpoint::get)).isEqualTo(dateTime);
}
@Test
void testSuccess_multipleWrites() {
DateTime firstTime = DateTime.parse("2012-02-29T00:00:00Z");
jpaTm().transact(() -> SqlReplayCheckpoint.set(firstTime));
DateTime secondTime = DateTime.parse("2013-02-28T00:00:00Z");
jpaTm().transact(() -> SqlReplayCheckpoint.set(secondTime));
assertThat(jpaTm().transact(SqlReplayCheckpoint::get)).isEqualTo(secondTime);
jpaTm()
.transact(
() ->
assertThat(
jpaTm()
.getEntityManager()
.createQuery("SELECT COUNT(*) FROM SqlReplayCheckpoint", Long.class)
.getSingleResult())
.isEqualTo(1L));
}
}

View file

@ -221,12 +221,6 @@ class DedupeRecurringBillingEventIdsCommandTest
}
}
private static void assertNotChangeInDatastore(ImmutableObject... entities) {
for (ImmutableObject entity : entities) {
assertThat(ofy().load().entity(entity).now()).isEqualTo(entity);
}
}
private static void assertNotChangeExceptUpdateTime(ImmutableObject... entities) {
for (ImmutableObject entity : entities) {
assertAboutImmutableObjects()

View file

@ -261,32 +261,32 @@ td.section {
</tr>
<tr>
<td class="property_name">generated on</td>
<td class="property_value">2020-11-09 17:11:19.905881</td>
<td class="property_value">2020-11-10 19:44:25.39289</td>
</tr>
<tr>
<td class="property_name">last flyway file</td>
<td id="lastFlywayFile" class="property_value">V73__singleton_entities.sql</td>
<td id="lastFlywayFile" class="property_value">V74__sql_replay_checkpoint.sql</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
<svg viewbox="0.00 0.00 6024.44 2289.50" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="erDiagram" style="overflow: hidden; width: 100%; height: 800px"> <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 2285.5)">
<svg viewbox="0.00 0.00 6024.44 2355.50" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="erDiagram" style="overflow: hidden; width: 100%; height: 800px"> <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 2351.5)">
<title>SchemaCrawler_Diagram</title>
<polygon fill="white" stroke="transparent" points="-4,4 -4,-2285.5 6020.44,-2285.5 6020.44,4 -4,4" />
<text text-anchor="start" x="5747.94" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<polygon fill="white" stroke="transparent" points="-4,4 -4,-2351.5 6020.44,-2351.5 6020.44,4 -4,4" />
<text text-anchor="start" x="5755.94" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">
generated by
</text>
<text text-anchor="start" x="5830.94" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="5838.94" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">
SchemaCrawler 16.10.1
</text>
<text text-anchor="start" x="5746.94" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="5754.94" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
generated on
</text>
<text text-anchor="start" x="5830.94" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
2020-11-09 17:11:19.905881
<text text-anchor="start" x="5838.94" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
2020-11-10 19:44:25.39289
</text>
<polygon fill="none" stroke="#888888" points="5743.44,-4 5743.44,-44 6008.44,-44 6008.44,-4 5743.44,-4" /> <!-- allocationtoken_a08ccbef -->
<polygon fill="none" stroke="#888888" points="5751.44,-4 5751.44,-44 6008.44,-44 6008.44,-4 5751.44,-4" /> <!-- allocationtoken_a08ccbef -->
<g id="node1" class="node">
<title>allocationtoken_a08ccbef</title>
<polygon fill="#ebcef2" stroke="transparent" points="4341.5,-976 4341.5,-995 4494.5,-995 4494.5,-976 4341.5,-976" />
@ -1352,7 +1352,7 @@ td.section {
fk_domain_transfer_losing_registrar_id
</text>
</g> <!-- tld_f1fa57e2 -->
<g id="node35" class="node">
<g id="node36" class="node">
<title>tld_f1fa57e2</title>
<polygon fill="#ebcef2" stroke="transparent" points="2521.5,-1406 2521.5,-1425 2594.5,-1425 2594.5,-1406 2521.5,-1406" />
<text text-anchor="start" x="2523.5" y="-1412.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
@ -3042,67 +3042,87 @@ td.section {
<text text-anchor="start" x="5489" y="-2060.8" font-family="Helvetica,sans-Serif" font-size="14.00">
fk5ivlhvs3121yx2li5tqh54u4
</text>
</g> <!-- sqlreplaycheckpoint_342081b3 -->
<g id="node35" class="node">
<title>sqlreplaycheckpoint_342081b3</title>
<polygon fill="#ebcef2" stroke="transparent" points="5721.5,-2134 5721.5,-2153 5908.5,-2153 5908.5,-2134 5721.5,-2134" />
<text text-anchor="start" x="5723.5" y="-2140.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
public.SqlReplayCheckpoint
</text>
<polygon fill="#ebcef2" stroke="transparent" points="5908.5,-2134 5908.5,-2153 5982.5,-2153 5982.5,-2134 5908.5,-2134" />
<text text-anchor="start" x="5943.5" y="-2139.8" font-family="Helvetica,sans-Serif" font-size="14.00">
[table]
</text>
<text text-anchor="start" x="5723.5" y="-2121.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
revision_id
</text>
<text text-anchor="start" x="5850.5" y="-2120.8" font-family="Helvetica,sans-Serif" font-size="14.00">
</text>
<text text-anchor="start" x="5910.5" y="-2120.8" font-family="Helvetica,sans-Serif" font-size="14.00">
int8 not null
</text>
<polygon fill="none" stroke="#888888" points="5720,-2114 5720,-2154 5983,-2154 5983,-2114 5720,-2114" />
</g> <!-- tmchcrl_d282355 -->
<g id="node36" class="node">
<g id="node37" class="node">
<title>tmchcrl_d282355</title>
<polygon fill="#ebcef2" stroke="transparent" points="5708.5,-2172 5708.5,-2191 5868.5,-2191 5868.5,-2172 5708.5,-2172" />
<text text-anchor="start" x="5710.5" y="-2178.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
<polygon fill="#ebcef2" stroke="transparent" points="5708.5,-2238 5708.5,-2257 5868.5,-2257 5868.5,-2238 5708.5,-2238" />
<text text-anchor="start" x="5710.5" y="-2244.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
public.TmchCrl
</text>
<polygon fill="#ebcef2" stroke="transparent" points="5868.5,-2172 5868.5,-2191 5994.5,-2191 5994.5,-2172 5868.5,-2172" />
<text text-anchor="start" x="5955.5" y="-2177.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<polygon fill="#ebcef2" stroke="transparent" points="5868.5,-2238 5868.5,-2257 5994.5,-2257 5994.5,-2238 5868.5,-2238" />
<text text-anchor="start" x="5955.5" y="-2243.8" font-family="Helvetica,sans-Serif" font-size="14.00">
[table]
</text>
<text text-anchor="start" x="5710.5" y="-2159.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
<text text-anchor="start" x="5710.5" y="-2225.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
certificate_revocations
</text>
<text text-anchor="start" x="5862.5" y="-2158.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="5862.5" y="-2224.8" font-family="Helvetica,sans-Serif" font-size="14.00">
</text>
<text text-anchor="start" x="5870.5" y="-2158.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="5870.5" y="-2224.8" font-family="Helvetica,sans-Serif" font-size="14.00">
text not null
</text>
<text text-anchor="start" x="5710.5" y="-2140.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
<text text-anchor="start" x="5710.5" y="-2206.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
update_timestamp
</text>
<text text-anchor="start" x="5862.5" y="-2139.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="5862.5" y="-2205.8" font-family="Helvetica,sans-Serif" font-size="14.00">
</text>
<text text-anchor="start" x="5870.5" y="-2139.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="5870.5" y="-2205.8" font-family="Helvetica,sans-Serif" font-size="14.00">
timestamptz not null
</text>
<text text-anchor="start" x="5710.5" y="-2121.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
<text text-anchor="start" x="5710.5" y="-2187.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
url
</text>
<text text-anchor="start" x="5862.5" y="-2120.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="5862.5" y="-2186.8" font-family="Helvetica,sans-Serif" font-size="14.00">
</text>
<text text-anchor="start" x="5870.5" y="-2120.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="5870.5" y="-2186.8" font-family="Helvetica,sans-Serif" font-size="14.00">
text not null
</text>
<polygon fill="none" stroke="#888888" points="5707.5,-2114 5707.5,-2192 5995.5,-2192 5995.5,-2114 5707.5,-2114" />
<polygon fill="none" stroke="#888888" points="5707.5,-2180 5707.5,-2258 5995.5,-2258 5995.5,-2180 5707.5,-2180" />
</g> <!-- transaction_d50389d4 -->
<g id="node37" class="node">
<g id="node38" class="node">
<title>transaction_d50389d4</title>
<polygon fill="#ebcef2" stroke="transparent" points="5734.5,-2257 5734.5,-2276 5859.5,-2276 5859.5,-2257 5734.5,-2257" />
<text text-anchor="start" x="5736.5" y="-2263.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
<polygon fill="#ebcef2" stroke="transparent" points="5734.5,-2323 5734.5,-2342 5859.5,-2342 5859.5,-2323 5734.5,-2323" />
<text text-anchor="start" x="5736.5" y="-2329.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
public.Transaction
</text>
<polygon fill="#ebcef2" stroke="transparent" points="5859.5,-2257 5859.5,-2276 5969.5,-2276 5969.5,-2257 5859.5,-2257" />
<text text-anchor="start" x="5930.5" y="-2262.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<polygon fill="#ebcef2" stroke="transparent" points="5859.5,-2323 5859.5,-2342 5969.5,-2342 5969.5,-2323 5859.5,-2323" />
<text text-anchor="start" x="5930.5" y="-2328.8" font-family="Helvetica,sans-Serif" font-size="14.00">
[table]
</text>
<text text-anchor="start" x="5736.5" y="-2244.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
<text text-anchor="start" x="5736.5" y="-2310.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
id
</text>
<text text-anchor="start" x="5803.5" y="-2243.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="5803.5" y="-2309.8" font-family="Helvetica,sans-Serif" font-size="14.00">
</text>
<text text-anchor="start" x="5861.5" y="-2243.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="5861.5" y="-2309.8" font-family="Helvetica,sans-Serif" font-size="14.00">
bigserial not null
</text>
<text text-anchor="start" x="5803.5" y="-2224.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="5803.5" y="-2290.8" font-family="Helvetica,sans-Serif" font-size="14.00">
</text>
<text text-anchor="start" x="5861.5" y="-2224.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="5861.5" y="-2290.8" font-family="Helvetica,sans-Serif" font-size="14.00">
auto-incremented
</text>
<polygon fill="none" stroke="#888888" points="5733,-2218.5 5733,-2277.5 5970,-2277.5 5970,-2218.5 5733,-2218.5" />
<polygon fill="none" stroke="#888888" points="5733,-2284.5 5733,-2343.5 5970,-2343.5 5970,-2284.5 5733,-2284.5" />
</g>
</g>
</svg>
@ -6755,6 +6775,36 @@ td.section {
</tbody>
</table>
<p>&nbsp;</p>
<table>
<caption style="background-color: #EBCEF2;"> <span id="sqlreplaycheckpoint_342081b3" class="caption_name">public.SqlReplayCheckpoint</span> <span class="caption_description">[table]</span>
</caption>
<tbody>
<tr>
<td class="spacer"></td>
<td class="minwidth"><b><i>revision_id</i></b></td>
<td class="minwidth">int8 not null</td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
<tr>
<td colspan="3" class="section">Primary Key</td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
<tr>
<td colspan="2" class="name">SqlReplayCheckpoint_pkey</td>
<td class="description right">[primary key]</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth">revision_id</td>
<td class="minwidth"></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table>
<caption style="background-color: #EBCEF2;"> <span id="tld_f1fa57e2" class="caption_name">public.Tld</span> <span class="caption_description">[table]</span>
</caption>

View file

@ -261,32 +261,32 @@ td.section {
</tr>
<tr>
<td class="property_name">generated on</td>
<td class="property_value">2020-11-09 17:11:18.25328</td>
<td class="property_value">2020-11-10 19:44:23.457057</td>
</tr>
<tr>
<td class="property_name">last flyway file</td>
<td id="lastFlywayFile" class="property_value">V73__singleton_entities.sql</td>
<td id="lastFlywayFile" class="property_value">V74__sql_replay_checkpoint.sql</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
<svg viewbox="0.00 0.00 6687.18 4086.50" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="erDiagram" style="overflow: hidden; width: 100%; height: 800px"> <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 4082.5)">
<svg viewbox="0.00 0.00 6687.18 4172.50" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="erDiagram" style="overflow: hidden; width: 100%; height: 800px"> <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 4168.5)">
<title>SchemaCrawler_Diagram</title>
<polygon fill="white" stroke="transparent" points="-4,4 -4,-4082.5 6683.18,-4082.5 6683.18,4 -4,4" />
<text text-anchor="start" x="6418.68" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<polygon fill="white" stroke="transparent" points="-4,4 -4,-4168.5 6683.18,-4168.5 6683.18,4 -4,4" />
<text text-anchor="start" x="6410.68" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">
generated by
</text>
<text text-anchor="start" x="6501.68" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="6493.68" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">
SchemaCrawler 16.10.1
</text>
<text text-anchor="start" x="6417.68" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="6409.68" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
generated on
</text>
<text text-anchor="start" x="6501.68" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
2020-11-09 17:11:18.25328
<text text-anchor="start" x="6493.68" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">
2020-11-10 19:44:23.457057
</text>
<polygon fill="none" stroke="#888888" points="6414.18,-4 6414.18,-44 6671.18,-44 6671.18,-4 6414.18,-4" /> <!-- allocationtoken_a08ccbef -->
<polygon fill="none" stroke="#888888" points="6406.18,-4 6406.18,-44 6671.18,-44 6671.18,-4 6406.18,-4" /> <!-- allocationtoken_a08ccbef -->
<g id="node1" class="node">
<title>allocationtoken_a08ccbef</title>
<polygon fill="#ebcef2" stroke="transparent" points="4893.5,-2257.5 4893.5,-2276.5 5059.5,-2276.5 5059.5,-2257.5 4893.5,-2257.5" />
@ -3048,7 +3048,7 @@ td.section {
fk_domain_transfer_losing_registrar_id
</text>
</g> <!-- tld_f1fa57e2 -->
<g id="node35" class="node">
<g id="node36" class="node">
<title>tld_f1fa57e2</title>
<polygon fill="#ebcef2" stroke="transparent" points="2732.5,-3813.5 2732.5,-3832.5 3011.5,-3832.5 3011.5,-3813.5 2732.5,-3813.5" />
<text text-anchor="start" x="2734.5" y="-3820.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
@ -6170,75 +6170,103 @@ td.section {
<text text-anchor="start" x="6084" y="-3841.3" font-family="Helvetica,sans-Serif" font-size="14.00">
fk5ivlhvs3121yx2li5tqh54u4
</text>
</g> <!-- tmchcrl_d282355 -->
<g id="node36" class="node">
<title>tmchcrl_d282355</title>
<polygon fill="#ebcef2" stroke="transparent" points="6329.5,-3950.5 6329.5,-3969.5 6489.5,-3969.5 6489.5,-3950.5 6329.5,-3950.5" />
<text text-anchor="start" x="6331.5" y="-3957.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
public.TmchCrl
</g> <!-- sqlreplaycheckpoint_342081b3 -->
<g id="node35" class="node">
<title>sqlreplaycheckpoint_342081b3</title>
<polygon fill="#ebcef2" stroke="transparent" points="6316.5,-3931.5 6316.5,-3950.5 6503.5,-3950.5 6503.5,-3931.5 6316.5,-3931.5" />
<text text-anchor="start" x="6318.5" y="-3938.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
public.SqlReplayCheckpoint
</text>
<polygon fill="#ebcef2" stroke="transparent" points="6489.5,-3950.5 6489.5,-3969.5 6615.5,-3969.5 6615.5,-3950.5 6489.5,-3950.5" />
<text text-anchor="start" x="6576.5" y="-3956.3" font-family="Helvetica,sans-Serif" font-size="14.00">
<polygon fill="#ebcef2" stroke="transparent" points="6503.5,-3931.5 6503.5,-3950.5 6629.5,-3950.5 6629.5,-3931.5 6503.5,-3931.5" />
<text text-anchor="start" x="6590.5" y="-3937.3" font-family="Helvetica,sans-Serif" font-size="14.00">
[table]
</text>
<text text-anchor="start" x="6331.5" y="-3938.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
certificate_revocations
<text text-anchor="start" x="6318.5" y="-3919.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
revision_id
</text>
<text text-anchor="start" x="6483.5" y="-3937.3" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="6459.5" y="-3918.3" font-family="Helvetica,sans-Serif" font-size="14.00">
</text>
<text text-anchor="start" x="6491.5" y="-3937.3" font-family="Helvetica,sans-Serif" font-size="14.00">
text not null
<text text-anchor="start" x="6505.5" y="-3918.3" font-family="Helvetica,sans-Serif" font-size="14.00">
int8 not null
</text>
<text text-anchor="start" x="6331.5" y="-3919.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
update_timestamp
<text text-anchor="start" x="6318.5" y="-3899.3" font-family="Helvetica,sans-Serif" font-size="14.00">
last_replay_time
</text>
<text text-anchor="start" x="6483.5" y="-3918.3" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="6459.5" y="-3899.3" font-family="Helvetica,sans-Serif" font-size="14.00">
</text>
<text text-anchor="start" x="6491.5" y="-3918.3" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="6505.5" y="-3899.3" font-family="Helvetica,sans-Serif" font-size="14.00">
timestamptz not null
</text>
<text text-anchor="start" x="6331.5" y="-3900.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
url
</text>
<text text-anchor="start" x="6483.5" y="-3899.3" font-family="Helvetica,sans-Serif" font-size="14.00">
</text>
<text text-anchor="start" x="6491.5" y="-3899.3" font-family="Helvetica,sans-Serif" font-size="14.00">
text not null
</text>
<polygon fill="none" stroke="#888888" points="6328.5,-3892.5 6328.5,-3970.5 6616.5,-3970.5 6616.5,-3892.5 6328.5,-3892.5" />
</g> <!-- transaction_d50389d4 -->
<polygon fill="none" stroke="#888888" points="6315,-3893 6315,-3952 6630,-3952 6630,-3893 6315,-3893" />
</g> <!-- tmchcrl_d282355 -->
<g id="node37" class="node">
<title>transaction_d50389d4</title>
<polygon fill="#ebcef2" stroke="transparent" points="6355.5,-4054.5 6355.5,-4073.5 6480.5,-4073.5 6480.5,-4054.5 6355.5,-4054.5" />
<text text-anchor="start" x="6357.5" y="-4061.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
public.Transaction
<title>tmchcrl_d282355</title>
<polygon fill="#ebcef2" stroke="transparent" points="6329.5,-4036.5 6329.5,-4055.5 6489.5,-4055.5 6489.5,-4036.5 6329.5,-4036.5" />
<text text-anchor="start" x="6331.5" y="-4043.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
public.TmchCrl
</text>
<polygon fill="#ebcef2" stroke="transparent" points="6480.5,-4054.5 6480.5,-4073.5 6590.5,-4073.5 6590.5,-4054.5 6480.5,-4054.5" />
<text text-anchor="start" x="6551.5" y="-4060.3" font-family="Helvetica,sans-Serif" font-size="14.00">
<polygon fill="#ebcef2" stroke="transparent" points="6489.5,-4036.5 6489.5,-4055.5 6615.5,-4055.5 6615.5,-4036.5 6489.5,-4036.5" />
<text text-anchor="start" x="6576.5" y="-4042.3" font-family="Helvetica,sans-Serif" font-size="14.00">
[table]
</text>
<text text-anchor="start" x="6357.5" y="-4042.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
<text text-anchor="start" x="6331.5" y="-4024.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
certificate_revocations
</text>
<text text-anchor="start" x="6483.5" y="-4023.3" font-family="Helvetica,sans-Serif" font-size="14.00">
</text>
<text text-anchor="start" x="6491.5" y="-4023.3" font-family="Helvetica,sans-Serif" font-size="14.00">
text not null
</text>
<text text-anchor="start" x="6331.5" y="-4005.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
update_timestamp
</text>
<text text-anchor="start" x="6483.5" y="-4004.3" font-family="Helvetica,sans-Serif" font-size="14.00">
</text>
<text text-anchor="start" x="6491.5" y="-4004.3" font-family="Helvetica,sans-Serif" font-size="14.00">
timestamptz not null
</text>
<text text-anchor="start" x="6331.5" y="-3986.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
url
</text>
<text text-anchor="start" x="6483.5" y="-3985.3" font-family="Helvetica,sans-Serif" font-size="14.00">
</text>
<text text-anchor="start" x="6491.5" y="-3985.3" font-family="Helvetica,sans-Serif" font-size="14.00">
text not null
</text>
<polygon fill="none" stroke="#888888" points="6328.5,-3978.5 6328.5,-4056.5 6616.5,-4056.5 6616.5,-3978.5 6328.5,-3978.5" />
</g> <!-- transaction_d50389d4 -->
<g id="node38" class="node">
<title>transaction_d50389d4</title>
<polygon fill="#ebcef2" stroke="transparent" points="6355.5,-4140.5 6355.5,-4159.5 6480.5,-4159.5 6480.5,-4140.5 6355.5,-4140.5" />
<text text-anchor="start" x="6357.5" y="-4147.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
public.Transaction
</text>
<polygon fill="#ebcef2" stroke="transparent" points="6480.5,-4140.5 6480.5,-4159.5 6590.5,-4159.5 6590.5,-4140.5 6480.5,-4140.5" />
<text text-anchor="start" x="6551.5" y="-4146.3" font-family="Helvetica,sans-Serif" font-size="14.00">
[table]
</text>
<text text-anchor="start" x="6357.5" y="-4128.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">
id
</text>
<text text-anchor="start" x="6443.5" y="-4041.3" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="6443.5" y="-4127.3" font-family="Helvetica,sans-Serif" font-size="14.00">
</text>
<text text-anchor="start" x="6482.5" y="-4041.3" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="6482.5" y="-4127.3" font-family="Helvetica,sans-Serif" font-size="14.00">
bigserial not null
</text>
<text text-anchor="start" x="6443.5" y="-4022.3" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="6443.5" y="-4108.3" font-family="Helvetica,sans-Serif" font-size="14.00">
</text>
<text text-anchor="start" x="6482.5" y="-4022.3" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="6482.5" y="-4108.3" font-family="Helvetica,sans-Serif" font-size="14.00">
auto-incremented
</text>
<text text-anchor="start" x="6357.5" y="-4003.3" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="6357.5" y="-4089.3" font-family="Helvetica,sans-Serif" font-size="14.00">
contents
</text>
<text text-anchor="start" x="6443.5" y="-4003.3" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="6443.5" y="-4089.3" font-family="Helvetica,sans-Serif" font-size="14.00">
</text>
<text text-anchor="start" x="6482.5" y="-4003.3" font-family="Helvetica,sans-Serif" font-size="14.00">
<text text-anchor="start" x="6482.5" y="-4089.3" font-family="Helvetica,sans-Serif" font-size="14.00">
bytea
</text>
<polygon fill="none" stroke="#888888" points="6354,-3996.5 6354,-4074.5 6591,-4074.5 6591,-3996.5 6354,-3996.5" />
<polygon fill="none" stroke="#888888" points="6354,-4082.5 6354,-4160.5 6591,-4160.5 6591,-4082.5 6354,-4082.5" />
</g>
</g>
</svg>
@ -12958,6 +12986,59 @@ td.section {
</tbody>
</table>
<p>&nbsp;</p>
<table>
<caption style="background-color: #EBCEF2;"> <span id="sqlreplaycheckpoint_342081b3" class="caption_name">public.SqlReplayCheckpoint</span> <span class="caption_description">[table]</span>
</caption>
<tbody>
<tr>
<td class="spacer"></td>
<td class="minwidth"><b><i>revision_id</i></b></td>
<td class="minwidth">int8 not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth">last_replay_time</td>
<td class="minwidth">timestamptz not null</td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
<tr>
<td colspan="3" class="section">Primary Key</td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
<tr>
<td colspan="2" class="name">SqlReplayCheckpoint_pkey</td>
<td class="description right">[primary key]</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth">revision_id</td>
<td class="minwidth"></td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
<tr>
<td colspan="3" class="section">Indexes</td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
<tr>
<td colspan="2" class="name">SqlReplayCheckpoint_pkey</td>
<td class="description right">[unique index]</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth">revision_id</td>
<td class="minwidth">ascending</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table>
<caption style="background-color: #EBCEF2;"> <span id="tld_f1fa57e2" class="caption_name">public.Tld</span> <span class="caption_description">[table]</span>
</caption>

View file

@ -71,3 +71,4 @@ V70__signed_mark_revocation_list.sql
V71__create_kms_secret.sql
V72__add_missing_foreign_keys.sql
V73__singleton_entities.sql
V74__sql_replay_checkpoint.sql

View file

@ -0,0 +1,19 @@
-- Copyright 2020 The Nomulus Authors. All Rights Reserved.
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
CREATE TABLE "SqlReplayCheckpoint" (
revision_id int8 not null,
last_replay_time timestamptz not null,
PRIMARY KEY(revision_id)
);

View file

@ -655,6 +655,12 @@
primary key (id)
);
create table "SqlReplayCheckpoint" (
revision_id int8 not null,
last_replay_time timestamptz,
primary key (revision_id)
);
create table "Tld" (
tld_name text not null,
add_grace_period_length interval not null,

View file

@ -948,6 +948,16 @@ CREATE SEQUENCE public."SignedMarkRevocationList_revision_id_seq"
ALTER SEQUENCE public."SignedMarkRevocationList_revision_id_seq" OWNED BY public."SignedMarkRevocationList".revision_id;
--
-- Name: SqlReplayCheckpoint; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public."SqlReplayCheckpoint" (
revision_id bigint NOT NULL,
last_replay_time timestamp with time zone NOT NULL
);
--
-- Name: Tld; Type: TABLE; Schema: public; Owner: -
--
@ -1346,6 +1356,14 @@ ALTER TABLE ONLY public."SignedMarkRevocationList"
ADD CONSTRAINT "SignedMarkRevocationList_pkey" PRIMARY KEY (revision_id);
--
-- Name: SqlReplayCheckpoint SqlReplayCheckpoint_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."SqlReplayCheckpoint"
ADD CONSTRAINT "SqlReplayCheckpoint_pkey" PRIMARY KEY (revision_id);
--
-- Name: Tld Tld_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--