1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002, 2014 Oracle and/or its affiliates.  All rights reserved.
5  *
6  */
7 
8 package com.sleepycat.je.log;
9 
10 import com.sleepycat.je.log.entry.DbOperationType;
11 import com.sleepycat.je.utilint.VLSN;
12 
13 /**
14  * ReplicationContext provides context about high-level operations so that the
15  * logging level can determine which replication related actions are required
16  * for a given Loggable item.
17  *
18  * Those lower level actions are:
19  * - does a log entry need to be logged with a VLSN generated by this
20  * (master) node?
21  * - does the log entry need to be logged with the VLSN which accompanied a
22  *   replication message?
23  * - do we need to wait for PERM acks after logging an entry?
24  * - do we need to record the client VLSN that was just written to the log?
25  *
26  * ReplicationContext subclasses may hold additional information about the
27  * logical operation which instigated logging, so that this can be added
28  * to the log entry.
29  *
30  * All LogEntryType(s) have a "replicationPossible" attribute. For example,
31  * INs will never be replicated, but LN_TX's may or may not be replicated,
32  * depending on whether the owning database is replicated.
33  *
34  * If a LogEntryType will never be replicated, it should be logged with
35  * the static ReplicationContext.NO_REPLICATE instance.
36  * If replication is possible, the replication context may be:
37  *   - one allocated for this operation, as the result of client apply
38  *   - the static instance MASTER, if this node is the replication master
39  *   - the static instance NO_REPLICATE, if this is a local operation
40  *
41  */
42 public class ReplicationContext {
43 
44     /*
45      * Convenience static instance used when you know this operation is
46      * executing on a replication master node.
47      */
48     public static final ReplicationContext MASTER =
49         new ReplicationContext(true /* inReplicationStream */);
50 
51     /*
52      * Convenience static instance used when you know this operation will not
53      * be replicated, either because it's executing on a non-replicated node,
54      * it's a local operation for a local database, it's a read only operation,
55      * or because this loggable item is the type that is never replicated.
56      */
57     public static final ReplicationContext NO_REPLICATE =
58         new ReplicationContext(false /* inReplicationStream */);
59 
60     /*
61      * If true, this Loggable item is part of the replication stream, and
62      * needs to be logged with a VLSN.
63      */
64     private final boolean inReplicationStream;
65 
66     /*
67      * The VLSN value passed in from a replication message directed at
68      * this replication client.
69      */
70     private final VLSN clientVLSN;
71 
ReplicationContext(boolean inReplicationStream)72     protected ReplicationContext(boolean inReplicationStream) {
73         this.inReplicationStream = inReplicationStream;
74         clientVLSN = null;
75     }
76 
77     /**
78      * Used to pass the VLSN held in an arriving message down to the logging
79      * levels.
80      */
ReplicationContext(VLSN clientVLSN)81     public ReplicationContext(VLSN clientVLSN) {
82         this.inReplicationStream = true;
83         this.clientVLSN = clientVLSN;
84     }
85 
86     /**
87      * Used to pass the VLSN held in a migrated LN down to the logging levels.
88      */
ReplicationContext(VLSN clientVLSN, boolean inReplicationStream)89     public ReplicationContext(VLSN clientVLSN, boolean inReplicationStream) {
90         this.clientVLSN = clientVLSN;
91         this.inReplicationStream = inReplicationStream;
92     }
93 
94     /**
95      * @return the VLSN that arrived in the replication message which
96      * instigated this Loggable item.
97      */
getClientVLSN()98     public VLSN getClientVLSN() {
99         return clientVLSN;
100     }
101 
102     /**
103      * @return true if this loggable item is part of the replication stream
104      */
inReplicationStream()105     public boolean inReplicationStream() {
106         return inReplicationStream;
107     }
108 
109     /**
110      * @return true if this node is the master, and should
111      * generate a VLSN for this log entry
112      */
mustGenerateVLSN()113     public boolean mustGenerateVLSN() {
114         return (inReplicationStream && (clientVLSN == null));
115     }
116 
117     /**
118      * @return the type of database operation in progress. For the default
119      * case, we return DbOperationType.NONE.
120      */
getDbOperationType()121     public DbOperationType getDbOperationType() {
122         return DbOperationType.NONE;
123     }
124 
125     @Override
toString()126     public String toString() {
127         StringBuilder sb = new StringBuilder();
128         sb.append("inRepStream=").append(inReplicationStream);
129         sb.append("clientVLSN=").append(clientVLSN);
130         return sb.toString();
131     }
132 }
133