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)
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