Skip to content

Commit f0c5ddc

Browse files
committed
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 c5776fb commit f0c5ddc

File tree

1 file changed

+106
-63
lines changed

1 file changed

+106
-63
lines changed

contrib/mmts/multimaster.c

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

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

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

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

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

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy