Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)