Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 6350d28

Browse files
knizhnikkelvich
authored andcommitted
Make it possible to specify multimaster nodes in separate file, update this file in mtm.add_node and try to determine node_id if multimaster in started at different hosts
1 parent c1790a6 commit 6350d28

File tree

1 file changed

+106
-63
lines changed

1 file changed

+106
-63
lines changed

multimaster.c

Lines changed: 106 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2049,22 +2049,18 @@ void MtmUpdateNodeConnectionInfo(MtmConnectionInfo* conn, char const* connStr)
20492049

20502050
port = strstr(connStr, "raftport=");
20512051
if (port != NULL) {
2052-
int n;
2053-
if (sscanf(port+9, "%d%n", &conn->raftablePort, &n) != 1) {
2052+
if (sscanf(port+9, "%d", &conn->raftablePort) != 1) {
20542053
elog(ERROR, "Invalid raftable port: %s", port+9);
20552054
}
2056-
n += 9;
20572055
} else {
20582056
conn->raftablePort = 0;
20592057
}
20602058

20612059
port = strstr(connStr, "arbiterport=");
20622060
if (port != NULL) {
2063-
int n;
2064-
if (sscanf(port+12, "%d%n", &conn->arbiterPort, &n) != 1) {
2061+
if (sscanf(port+12, "%d", &conn->arbiterPort) != 1) {
20652062
elog(ERROR, "Invalid arbiter port: %s", port+12);
20662063
}
2067-
n += 12;
20682064
} else {
20692065
conn->arbiterPort = 0;
20702066
}
@@ -2073,23 +2069,29 @@ void MtmUpdateNodeConnectionInfo(MtmConnectionInfo* conn, char const* connStr)
20732069
static void MtmSplitConnStrs(void)
20742070
{
20752071
int i;
2076-
char* copy = pstrdup(MtmConnStrs);
2077-
char* connStr = copy;
2078-
char* connStrEnd = connStr + strlen(connStr);
2079-
2080-
for (i = 0; connStr < connStrEnd; i++) {
2081-
char* p = strchr(connStr, ',');
2082-
if (p == NULL) {
2083-
p = connStrEnd;
2084-
}
2085-
connStr = p + 1;
2072+
FILE* f = NULL;
2073+
char buf[MULTIMASTER_MAX_CTL_STR_SIZE];
2074+
2075+
if (*MtmConnStrs == '@') {
2076+
f = fopen(MtmConnStrs+1, "r");
2077+
for (i = 0; fgets(buf, sizeof buf, f) != NULL; i++) {
2078+
if (strlen(buf) <= 1) {
2079+
elog(ERROR, "Empty lines are not allowed in %s file", MtmConnStrs+1);
2080+
}
2081+
}
2082+
} else {
2083+
char* p = MtmConnStrs;
2084+
for (i = 0; *p != '\0'; i++) {
2085+
if ((p = strchr(p, ',')) == NULL) {
2086+
i += 1;
2087+
break;
2088+
}
2089+
}
20862090
}
2091+
20872092
if (i > MAX_NODES) {
20882093
elog(ERROR, "Multimaster with more than %d nodes is not currently supported", MAX_NODES);
20892094
}
2090-
if (MtmNodeId > i) {
2091-
elog(ERROR, "Multimaster node id %d is out of range [%d..%d]", MtmNodeId, 1, i);
2092-
}
20932095
if (i < 2) {
20942096
elog(ERROR, "Multimaster should have at least two nodes");
20952097
}
@@ -2100,56 +2102,89 @@ static void MtmSplitConnStrs(void)
21002102
}
21012103
MtmNodes = i;
21022104
MtmConnections = (MtmConnectionInfo*)palloc(MtmMaxNodes*sizeof(MtmConnectionInfo));
2103-
connStr = copy;
21042105

2105-
for (i = 0; connStr < connStrEnd; i++) {
2106-
char* p = strchr(connStr, ',');
2107-
if (p == NULL) {
2108-
p = connStrEnd;
2109-
}
2110-
*p = '\0';
2111-
2112-
MtmUpdateNodeConnectionInfo(&MtmConnections[i], connStr);
2113-
2114-
if (i+1 == MtmNodeId) {
2115-
char* dbName = strstr(connStr, "dbname="); // XXX: shoud we care about string 'itisnotdbname=xxx'?
2116-
char* dbUser = strstr(connStr, "user=");
2117-
char* end;
2118-
size_t len;
2119-
2120-
if (dbName == NULL)
2121-
elog(ERROR, "Database is not specified in connection string: '%s'", connStr);
2122-
2123-
if (dbUser == NULL)
2124-
{
2125-
char *errstr;
2126-
const char *username = get_user_name(&errstr);
2127-
if (!username)
2128-
elog(FATAL, "Database user is not specified in connection string '%s', fallback failed: %s", connStr, errstr);
2129-
else
2130-
elog(WARNING, "Database user is not specified in connection string '%s', fallback to '%s'", connStr, username);
2131-
MtmDatabaseUser = pstrdup(username);
2106+
if (f != NULL) {
2107+
fseek(f, SEEK_SET, 0);
2108+
for (i = 0; fgets(buf, sizeof buf, f) != NULL; i++) {
2109+
size_t len = strlen(buf);
2110+
if (buf[len-1] == '\n') {
2111+
buf[len-1] = '\0';
2112+
}
2113+
MtmUpdateNodeConnectionInfo(&MtmConnections[i], buf);
2114+
}
2115+
fclose(f);
2116+
} else {
2117+
char* copy = pstrdup(MtmConnStrs);
2118+
char* connStr = copy;
2119+
char* connStrEnd = connStr + strlen(connStr);
2120+
2121+
for (i = 0; connStr != connStrEnd; i++) {
2122+
char* p = strchr(connStr, ',');
2123+
if (p == NULL) {
2124+
p = connStrEnd;
21322125
}
2133-
else
2134-
{
2135-
dbUser += 5;
2136-
end = strchr(dbUser, ' ');
2137-
if (!end) end = strchr(dbUser, '\0');
2138-
Assert(end != NULL);
2139-
len = end - dbUser;
2140-
MtmDatabaseUser = pnstrdup(dbUser, len);
2126+
*p = '\0';
2127+
MtmUpdateNodeConnectionInfo(&MtmConnections[i], connStr);
2128+
connStr = p + 1;
2129+
}
2130+
pfree(copy);
2131+
}
2132+
if (MtmNodeId == INT_MAX) {
2133+
if (gethostname(buf, sizeof buf) != 0) {
2134+
elog(ERROR, "Failed to get host name: %m");
2135+
}
2136+
for (i = 0; i < MtmNodes; i++) {
2137+
if (strcmp(MtmConnections[i].hostName, buf) == 0) {
2138+
if (MtmNodeId == INT_MAX) {
2139+
MtmNodeId = i+1;
2140+
} else {
2141+
elog(ERROR, "multimaster.node_id is not explicitly specified and more than one nodes are configured for host %s", buf);
2142+
}
21412143
}
2142-
2143-
dbName += 7;
2144-
end = strchr(dbName, ' ');
2145-
if (!end) end = strchr(dbName, '\0');
2144+
}
2145+
if (MtmNodeId == INT_MAX) {
2146+
elog(ERROR, "multimaster.node_id and host name %s can not be located in connection strings list", buf);
2147+
}
2148+
} else if (MtmNodeId > i) {
2149+
elog(ERROR, "Multimaster node id %d is out of range [%d..%d]", MtmNodeId, 1, MtmNodes);
2150+
}
2151+
{
2152+
char* connStr = MtmConnections[MtmNodeId-1].connStr;
2153+
char* dbName = strstr(connStr, "dbname="); // XXX: shoud we care about string 'itisnotdbname=xxx'?
2154+
char* dbUser = strstr(connStr, "user=");
2155+
char* end;
2156+
size_t len;
2157+
2158+
if (dbName == NULL)
2159+
elog(ERROR, "Database is not specified in connection string: '%s'", connStr);
2160+
2161+
if (dbUser == NULL)
2162+
{
2163+
char *errstr;
2164+
const char *username = get_user_name(&errstr);
2165+
if (!username)
2166+
elog(FATAL, "Database user is not specified in connection string '%s', fallback failed: %s", connStr, errstr);
2167+
else
2168+
elog(WARNING, "Database user is not specified in connection string '%s', fallback to '%s'", connStr, username);
2169+
MtmDatabaseUser = pstrdup(username);
2170+
}
2171+
else
2172+
{
2173+
dbUser += 5;
2174+
end = strchr(dbUser, ' ');
2175+
if (!end) end = strchr(dbUser, '\0');
21462176
Assert(end != NULL);
2147-
len = end - dbName;
2148-
MtmDatabaseName = pnstrdup(dbName, len);
2177+
len = end - dbUser;
2178+
MtmDatabaseUser = pnstrdup(dbUser, len);
21492179
}
2150-
connStr = p + 1;
2180+
2181+
dbName += 7;
2182+
end = strchr(dbName, ' ');
2183+
if (!end) end = strchr(dbName, '\0');
2184+
Assert(end != NULL);
2185+
len = end - dbName;
2186+
MtmDatabaseName = pnstrdup(dbName, len);
21512187
}
2152-
pfree(copy);
21532188
}
21542189

21552190
static bool ConfigIsSane(void)
@@ -2993,7 +3028,15 @@ mtm_add_node(PG_FUNCTION_ARGS)
29933028
MtmLock(LW_EXCLUSIVE);
29943029
nodeId = Mtm->nAllNodes;
29953030
elog(NOTICE, "Add node %d: '%s'", nodeId+1, connStr);
3031+
29963032
MtmUpdateNodeConnectionInfo(&Mtm->nodes[nodeId].con, connStr);
3033+
3034+
if (*MtmConnStrs == '@') {
3035+
FILE* f = fopen(MtmConnStrs+1, "a");
3036+
fprintf(f, "%s\n", connStr);
3037+
fclose(f);
3038+
}
3039+
29973040
Mtm->nodes[nodeId].transDelay = 0;
29983041
Mtm->nodes[nodeId].lastStatusChangeTime = MtmGetSystemTime();
29993042
Mtm->nodes[nodeId].flushPos = 0;

0 commit comments

Comments
 (0)